{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x7fcbb8149d50>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "from torch import nn, optim, autograd\n",
    "from torch.nn import functional as F\n",
    "from torch.distributions.multivariate_normal import MultivariateNormal\n",
    "from torch.autograd import Variable\n",
    "import numpy as np\n",
    "#import input_data\n",
    "from sklearn.utils import shuffle as skshuffle\n",
    "from math import *\n",
    "from backpack import backpack, extend\n",
    "from backpack.extensions import KFAC, DiagHessian, DiagGGNMC\n",
    "from sklearn.metrics import roc_auc_score\n",
    "import scipy\n",
    "from tqdm import tqdm, trange\n",
    "from bpjacext import NetJac\n",
    "import pytest\n",
    "from DirLPA_utils import * \n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "np.random.seed(123)\n",
    "torch.manual_seed(123)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#NOTE: DO NOT RUN THIS CODE: the function NetJac comes from a private repository that is not yet available for you. \n",
    "#If you search for it aggressively you might find out my identity. I would therefore prefer if you just looked at the provided results.\n",
    "\n",
    "#Also, Pytorch was updated and is now incompatible with NetJac."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# make plots work"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from matplotlib import cm\n",
    "from matplotlib.colors import ListedColormap, LinearSegmentedColormap\n",
    "\n",
    "new_blue = cm.get_cmap('Blues', 256)\n",
    "new_blue = new_blue(np.linspace(0.3,1,256))\n",
    "new_blues = ListedColormap(new_blue, name='new_blues')\n",
    "\n",
    "new_red = cm.get_cmap('Reds', 256)\n",
    "new_red = new_red(np.linspace(0.3,1,256))\n",
    "new_reds = ListedColormap(new_red, name='new_reds')\n",
    "\n",
    "new_green = cm.get_cmap('Greens', 256)\n",
    "new_green = new_green(np.linspace(0.3,1,256))\n",
    "new_greens = ListedColormap(new_green, name='new_greens')\n",
    "\n",
    "new_purple = cm.get_cmap('Purples', 256)\n",
    "new_purple = new_purple(np.linspace(0.3,1,256))\n",
    "new_purples = ListedColormap(new_purple, name='new_purples')\n",
    "\n",
    "new_orange = cm.get_cmap('Oranges', 256)\n",
    "new_orange = new_orange(np.linspace(0.3,1,256))\n",
    "new_oranges = ListedColormap(new_orange, name='new_oranges')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "top = cm.get_cmap('Blues_r', 128)\n",
    "bottom = cm.get_cmap('Reds', 128)\n",
    "\n",
    "\n",
    "newcolors = np.vstack((top(np.linspace(0.9, 1, 128)),\n",
    "                       bottom(np.linspace(0, 0.7, 128))))\n",
    "newcmp = ListedColormap(newcolors, name='OrangeBlue')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_coolwarm = cm.get_cmap('coolwarm', 256)\n",
    "new_coolwarm = new_coolwarm(np.linspace(0.35,0.95,256))\n",
    "new_coolwarm = ListedColormap(new_coolwarm, name='new_coolwarm')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_cool = cm.get_cmap('cool', 256)\n",
    "new_cool = new_cool(np.linspace(0.3,1 ,256))\n",
    "new_cool = ListedColormap(new_cool, name='new_cool')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_bupu = cm.get_cmap('BuPu', 256)\n",
    "new_bupu = new_bupu(np.linspace(0.4,1 ,256))\n",
    "new_bupu = ListedColormap(new_bupu, name='new_bupu')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "153\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZEAAAEHCAYAAABvHnsJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAACZNJREFUeJzt3DuS68YVgOFDgOS4JFd5S469Ay/DiXeiJThXOXTiwKEiK1U5cKLAgVV6+A5BAqSDuZLua2bIJkH04/tWQALd/Z++Q2l1Op0CAFJ0S38AAMolIgAkExEAkokIAMlEBIBkIgIv+PKr6fTlV5OfMMIzRASAZCICz3j3BuI2Ap8mIvAJogHnERE4k7DAx0QEPvBSLIQE3iciACQTEXjHOTcNtxH4lYgAkExE4K1LbhhuI/BERCDSoiAkICIAXEFEaN41Nwq3EVonIgAkExGadoubhNsILRMRAJKJCM265Q3CbYRWiQhNmuPQFxJaJCIAJBMRmjPnjcFthNaICADJRISm3OOm4DZCS0SEZjjc4fZEBGYgWLRCRGjCEoe6kNACEQEgmYhQvSVvBG4j1E5EAEgmIlQth5tADp8B5iIiVMvhDfMTEbgDQaNWIkKVcjy0c/xMcC0RASCZiFCdnCf+nD8bpBARAJKJCFUpYdIv4TPCuUSEapR0OJf0WeElIgJAMhGhCiVO9iV+ZviQiACQTEQoXskTfcmfHSJEBIAriAhFq2GSr+E70C4RoVg1Hb41fRfaIiIAJBMRilTj5F7jd6J+IgJAMhGhODVP7DV/N+okIhTFIQt5ERHIjFBSEhGhGC0dri19V8omIgAkExGK0OJk3uJ3pjwiAkAyESF7LU/kLX93yiAiZM0hCnkTEcickJIzESFbDs9feRbkSkQASCYiZMnk/THPhByJCADJRITsmLif59mQGxEhKw7J13lG5EREAEgmImTDhH0+z4pciAgAyUSELJisL+eZkQMRYXEOQyiXiEDBBJiliQiLcghezzNkSSICQDIRYTEm6NvxLFmKiACQTERYhMn59jxTliAi3J3DDuohIlARgebeRIS7csjNzzPmnkQEgGQiwt2YkO/Hs+ZeRASAZCLCXZiM788z5x5EhNk5zJbj2TM3EQEgmYgwK5Pw8rwD5iQiACQTEWZjAs6Hd8FcRASAZCLCLEy++fFOmIOIcHMOq3x5N9yaiACQTES4KZNu/rwjbklEAEgmItyMCbcc3hW3IiLchEMJ2iQi0Cjh5xZEhKs5jMrl3XEtEQEgmYhwFZNs+bxDriEiACQTEZKZYOvhXZJKREji0AEiRAR4y2BAChHhYg6benm3XEpEAEgmIlzEpFo/75hLiAgAyUSEs5lQ2+Fdcy4R4SwOlfZ455xDRABIJiK8ykTaLu+e14gIAMlEhBeZRLEGeImIAJBMRHiWCZSfWQs8R0T4JIcGH7Im+BQRASCZiPAREyfPsTb4kIgAkExEeI9Jk9dYI7xLRPiFwwG4lIgAFzNw8DMRISIcClzOmiFCRAC4gohgoiSZtYOIAJBMRBpnkuRa1lDbRKRhNj9wLREBrmYgaZeINMqm59asqTaJCADJRKRBJkbmYm21R0QASCYijTEpMjdrrC0i0hCbm3ux1tohIgAkE5FGmAy5N2uuDSICQDIRaYCJkKVYe/UTEQCSiUjlTIIszRqsm4hUzOYlF9ZivUQEgGQiUimTH7mxJuskIgAkE5EKmfjIlbVZHxGpjE0K3JOIAHdl0KmLiFTE5qQU1mo9RASAZCJSCZMdpbFm6yAiACQTkQqY6CiVtVs+ESmcTQgsSUSARRmEyiYiBbP5qIW1XC4RASCZiBTK5EZtrOkyiQgAyUSkQCY2amVtl0dECmOTUTtrvCwiAkAyESmICY1WWOvlEBEAkolIIUxmtMaaL4OIFMBmAnIlIkC2DFD5E5HM2US0zh7Im4gAkExEMmYCgyf2Qr5EBIBkIpIpkxe8z57Ik4hkyGYBSiEiQDEMWPkRkczYJPAyeyQvIgJAMhHJiAkLzmOv5ENEAEgmIpkwWcFl7Jk8iEgGbAZIY+8sT0QASCYiCzNJwXXsoWWJCADJRGRBJii4DXtpOSICQDIRWYjJCW7LnlqGiCzAYod52Fv3JyIAJBOROzMpwbzssfsSEQCSicgdmZDgPuy1+xGRO7GogRqJCFAlg9t9iMgdWMywDHtvfiICQDIRmZlJCJZlD85LRABIJiIzMgFBHuzF+YjITCxaoAUiAjTBYDcPEZmBxQp5sjdvT0QASCYiN2bSgbzZo7clIgAkE5EbMuFAGezV2xGRG7EooSz27G2ICADJROQGTDRQJnv3eiICQDIRuZJJBspmD19HRABIJiJXMMFAHezldCKSyKKDutjTaUQEgGQiksDEAnWyty8nIgAkE5ELmVSgbvb4ZUTkAhYXwPtEBOADBsbziciZLCpoiz1/HhEBIJmInMFEAm2y918nIgAkE5FXmESgbc6Al4nICywegJeJCMArDJTPE5FnWDTAu5wJnyYiACQTkU8wcQCf4mz4mIgAkExEPmDSAF7ijHifiLzD4gDO4az4lYgAkExE3jJZAJdwZjwREQCSiUhE/O2f+9O6N1QAl3EbEZGIiPh8s4+Hflr6YwAUp/mIfP3Nf07bfozteoptf1z64wCFaf020nREvvnXv0+/6Xbx0O1j243xsJmiWy39qYDStBySpiPy2fRDbGIf69UY236Mh36K7do/awGcq9mI/Pfrf5y2hzexmXaxWR1i2x1i3Y2x6Y/Rd80OFUCiVm8j66U/wFI2ux+i234ex24dU7eJadXHtlvH2K9jWnfxZt8v/REBstfkTeTx73859cOb6KYh1tMQ6+M+1vF0G3noD7Ht/ZEduFyLt5HmbiK7v35xWnVdxGe/jX6/iWO3iU23jbHbxrRax6Fbx7bvY1x3sZ+abCzA2Zo7JU8/fB8x7GK1H2K130U/7mI97WI7PsYm9vGwevql1rYf3UaAi7V2G2kqIj998efT9NOPcRp2EcMuunEf3biP/rCL9TTE5jj88kf2TTf5yS+QpKWQNBWR/Xffx3E3xOnxMWI/vL2R7KIbh+infWymIdZx8JNfgDM1E5Fv//TH0/i/x5ged3Ec9nEahoj9Lrrh8ekmcngT63H30U9+H/op/H+1gEu1chtp5g/ru+9+jIfffR79wzaOu110D9tYbdYRm+3TbaTfxLofYtNvf/nJ70Pfx3TsYzx2MU7NPCqAszVxE/n6D78/DT8OMQ2HGB+HmB6HOO52cdztIoanP7B3h+G9n/xuVvvYrg6x7Z/+A0R/ZAcu1cJtpImIPH73GOMwxuHNEONuH9Owf/onrf0+4jBEjIdYjfvoDkP04z424xDr4yH61fT0X7F3U2xEBOAjq9Op+lACMJMmbiIAzENEAEgmIgAkExEAkokIAMlEBIBk/wfgoN3Cf7CjsAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# just copy pasted from this link: http://blog.bogatron.net/blog/2014/02/02/visualizing-dirichlet-distributions/\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import matplotlib.tri as tri\n",
    "import math\n",
    "from functools import reduce\n",
    "from math import gamma\n",
    "from operator import mul\n",
    "from scipy.special import loggamma, gammaln, xlogy\n",
    "\n",
    "corners = np.array([[0, 0], [1, 0], [0.5, 0.75**0.5]])\n",
    "triangle = tri.Triangulation(corners[:, 0], corners[:, 1])\n",
    "\n",
    "refiner = tri.UniformTriRefiner(triangle)\n",
    "trimesh = refiner.refine_triangulation(subdiv=4)\n",
    "\n",
    "\n",
    "midpoints = [(corners[(i + 1) % 3] + corners[(i + 2) % 3]) / 2.0 \\\n",
    "             for i in range(3)]\n",
    "def xy2bc(xy, tol=1.e-3):\n",
    "    '''Converts 2D Cartesian coordinates to barycentric.'''\n",
    "    s = [(corners[i] - midpoints[i]).dot(xy - midpoints[i]) / 0.75 \\\n",
    "         for i in range(3)]\n",
    "    return np.clip(s, tol, 1.0 - tol)\n",
    "\n",
    "def logit_transform(x):\n",
    "    \n",
    "    out = np.log(x/(1-x))\n",
    "    return(out)\n",
    "\n",
    "def beta_function(alpha):\n",
    "    return(np.exp(np.sum([loggamma(a_i) for a_i in alpha]) - loggamma(np.sum(alpha))))    \n",
    "\n",
    "class Dirichlet(object):\n",
    "    def __init__(self, alpha):\n",
    "        self._alpha = np.array(alpha)\n",
    "        self._coef = np.sum(gammaln(alpha)) - gammaln(np.sum(alpha))    \n",
    "        \n",
    "    def pdf(self, x):\n",
    "        '''Returns pdf value for `x`.'''\n",
    "        #x = softmax_transform(x)\n",
    "        return(np.exp(- self._coef+ np.sum((xlogy(self._alpha-1, x.T)).T, 0)))\n",
    "    \n",
    "class Normal3D(object):\n",
    "    \n",
    "    def __init__(self, mu, Sigma):\n",
    "        self.mu = np.array(mu)\n",
    "        self.Sigma = np.linalg.inv(np.array(Sigma))\n",
    "        self.const = 1 / (np.sqrt((2*np.pi)**3 * np.linalg.det(Sigma)))\n",
    "        \n",
    "    def pdf(self, x):\n",
    "        \"\"\"Calculate 3D Gaussian\"\"\"\n",
    "        y = self.const * np.exp(-0.5 * (x - self.mu).T @ self.Sigma @ (x - self.mu))\n",
    "        return(y)\n",
    "    \n",
    "class logitNormal3D(object):\n",
    "    \n",
    "    def __init__(self, mu, Sigma):\n",
    "        self.mu = np.array(mu)\n",
    "        self.Sigma = np.array(Sigma)\n",
    "        self.Sigma_inv = np.linalg.inv(np.array(Sigma))\n",
    "        self.const = 1/ (np.sqrt(np.linalg.det(2 * np.pi * self.Sigma)))\n",
    "        \n",
    "    def pdf(self, x):\n",
    "        part_one = self.const /np.prod(x*(1-x))\n",
    "        logit = logit_transform(x)\n",
    "        part_two = np.exp(-0.5*(logit - self.mu).T @ self.Sigma_inv @ (logit - self.mu))\n",
    "        y = part_one * part_two\n",
    "        return(y)\n",
    "    \n",
    "class softmaxNormal3D(object):\n",
    "    \n",
    "    def __init__(self, mu, Sigma, c):\n",
    "        self.mu = np.array(mu)\n",
    "        self.c = c * np.ones(len(mu))\n",
    "        self.Sigma = np.array(Sigma)\n",
    "        self.Sigma_inv = np.linalg.inv(np.array(Sigma))\n",
    "        self.const = 1/ (np.sqrt(np.linalg.det(2 * np.pi * self.Sigma)))\n",
    "        \n",
    "    def pdf(self, x):\n",
    "        part_one = self.const/ np.prod(1/x)\n",
    "        sm_inv = np.log(x) + self.c\n",
    "        part_two = np.exp(-0.5*(sm_inv - self.mu).T @ self.Sigma_inv @ (sm_inv - self.mu))\n",
    "        y = part_one * part_two\n",
    "        return(y)\n",
    "\n",
    "def draw_pdf_contours(dist, nlevels=200, subdiv=4, filename='test.png',**kwargs):\n",
    "\n",
    "    refiner = tri.UniformTriRefiner(triangle)\n",
    "    trimesh = refiner.refine_triangulation(subdiv=subdiv)\n",
    "    pvals = [dist.pdf(xy2bc(xy)) for xy in zip(trimesh.x, trimesh.y)]\n",
    "    xys = [xy2bc(xy) for xy in zip(trimesh.x, trimesh.y)]\n",
    "    #print(len(pvals))\n",
    "    #print(xys)\n",
    "    print(len(xys))\n",
    "\n",
    "    cs = plt.tricontourf(trimesh, pvals, nlevels, cmap=new_coolwarm) #plasma, inferno is OK\n",
    "    for c in cs.collections:\n",
    "        c.set_rasterized(True)\n",
    "    plt.axis('equal')\n",
    "    plt.xlim(0, 1)\n",
    "    plt.ylim(0, 0.75**0.5)\n",
    "    plt.axis('off')\n",
    "    plt.tight_layout()\n",
    "    plt.margins(0,0)\n",
    "    plt.gca().xaxis.set_major_locator(plt.NullLocator())\n",
    "    plt.gca().yaxis.set_major_locator(plt.NullLocator())\n",
    "    plt.savefig('figures/{}'.format(filename), bbox_inches = 'tight', pad_inches = 0)\n",
    "    \n",
    "draw_pdf_contours(Dirichlet([100, 1,1]), filename='new_coolwarm.pdf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAbgAAADgCAYAAABxYHOdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJztnXl0HNd15r/bGxobAYLgAhIkSIqUKJISV62WLFqSZUqWLctxYnsmiRJ7rCRjxckcz2Ts6Mxk8czJNhPHk2SSMLFGysTxbo8UWbE2a6c2khJ3UqK4LyAIktiX3u78gaaIr14TANHVhWrw/s6pQ96qt1Whbr2q19+7T1QVhmEYhjHZiEx0AwzDMAyjFFgHZxiGYUxKrIMzDMMwJiXWwRmGYRiTEuvgDMMwjEmJdXCGYRjGpGTUDk5EkiLyhohsFZGdIvIH+f0LROR1EdknIt8VkUTpm2sYE4eIREXkLRF5vARlm58ZBvz1s7F8wQ0CuFVVVwBYCWC9iFwP4E8AfF1VFwE4C+DzxTbGMELObwHYXaKyzc8MYwjf/GzUDk6H6Mmb8fymAG4F8IP8/kcAfMKPBhlGGBGRZgAfBfAPpSjf/Mww/PezMf0Gl/9kfBtAG4CnAbwHoENVM/kkRwHM8aNBhhFS/gLA7wDIlaoC8zPD8NfPYmNJpKpZACtFpB7AjwEsGWsFInI/gPsBQBKJNfGZM84f85xCxckBsjPz3eblVNgejI5YfyRdoE2e6GSeIpGoS7n1tvFPH6laT55KrijdE3fbUpXldpzltmcr3LZqfOTGiuf8NOGGXov2eU6wLkNmrs+9zrF+tr1tU89lL1RvvIPr7T17tF1VpzsJx8FHPlStp89kR084BjZvG9wJYPjNt0FVN5wzRORuAG2qullE1vlSaQH88rPqZMWay+c1DTvI77E90Xqya3qPuwVGPO++8QI3pweN8j2v4rlXvWEBuzucMjL1M8iOp3o4Qb/nxgSA6hq2B/q4zOqpZMeyg04RkvE4kqft3nMbysPPiWyiiuxIbydnqKx2ysjE+LpGs1ym5Nx73NvWVGWdk2bHjh2++dr1dXXakcmMnnAU9vb1Be5nY+rgzqGqHSLyHIAbANSLSCz/dtkM4NgF8mwAsAEAKubN1Tlf/g/vH4t4+pHFf/oO2e3/q8Epr2eAb4jUe56exvMsr2z17AAQ9dzLOc9VmP2xQ06evr9oJvvYOn4AzFvOD4kTG90X7eSqM2RXfJ8dr2Ox29bB2dxYSXO9yVbuafqb3R69YQs7p3z0NNm9m6a5eXbz20fnZVxv2uOrmbn8cgIATY/xS8Gr3/+P7oUdJ+1nsnj9yebRE46BeNN7A6q6doQkHwDwcRG5C0ASwBQR+SdV/UVfGuChWD9bfcUCfeVv/vD8Mc9D9JW6e8i+8Y2vOeVFKvlhrXMXjtruVN0ssnNRdqxIlh+Skecfc8po+9hvkj3n0MtkZ3dvdytecxOXu+ctss/c+HNkTz29zykievoE74ixz6QbmuAlfuoI2d3zV5Fd/dpPyM4tv8Yp4/S0y7ltnQe5GQOeDh5A5ORRsk+s+KiTZuGixb75Wmcmg4eXLyu6nBveeDNwPxuLinJ6/o0SIlIJ4MMY+gHwOQCfyie7D8Cj422EYVw8iqzmfNlGrUn1q6rarKrzAXwGwM/87tzMz4zQIoBEpOhtNErhZ2P5gmsC8IiIRDHUIX5PVR8XkV0AviMi/w3AWwC+WUxDDONiUAAZ+DNEGRLMz4yQIohER++gwsioHZyqbgOwqsD+/QCuLUWjDGM0FIrsBCz1pKrPA3i+BOWanxlGHr/87KJ+gzOMsKAA0qUTNBqGkUcEiMRHFvOFFevgjLIlB1us1zCMCxNoBxfrBxqGiaCqPsvKpdwPkmTrPzY6ZczezxLf936e3+Ily2PF3Ve68lavEnHFsoMXbPM5Dq3gN5g7btpC9os/XE22epTLANC/lVWhA5fx8eiyLidPPM31xnayfLHqOlZEDp51pci5O7u5jP/HqsnqAsPrXfP4GuU8Kum71r9B9kt/646iNf32u7zj+24940WBCRmiLAey8Up0zL7qfbv22X+m49elXyO7a/0vO2WcjrEictH+f+UEUfeNPnnUE3zCo0Qc3MEKyEJ/vZmnd5Hd9+ILZMc//mknT3SA72+9YgXZ9WcPkB15j+sYKpgfhemFy7mObXzNhgpmFXT1mz8lu+sD95ItBQRNdd0sihWP0rT3X91oVbl/+wDZDT/6hts2P8mLTMoR+4IzyhKFIm1fcIYRAJNYZGIYoUSBrPVvhlFyxL7gDCNYFCWMmWUYxqTAOjijLFEI0t4Ya4ZhlATxhm4rE6yDM8qWrDcum2EY/mNDlGMjUwW0rzk/sJR8efaI6QfWuUFRsxWstESUo1l8+NptZD/zCiuqAGD2slayOwe5zIPH3Bil1Z5Qi888y6rJiEe8mGpyY0LGW1lVlrz6LNnyLKuyACBxO8evTK/yBEp+whNH8gp34K47wj9WVXGsXfQ1uT9mZWv5ujbN5XY8/zCrJivuPeWUse3YyH/fYlBYB3chYqk+TD20+X07fc0tdNx71abuegFeYktu4B2eoL+9G19x8lR9kOvJ7tlJdrSSY2LGmuc5ZQx64mZW3vYRsnWw18kTbfeosaexAlT2biW7f81tThnJzc9y2/awSrrnejfeY23rXrIjOfa9ZD/7d0XnSacM8QRkzh7l+JaRz3zByVP14o/Ijs6b66TxFxOZGEagKIC0luewiWGUEyYyMYyAUQiyY1vO0DCMSxTr4Iyyxbs2oGEYpcFEJoYRIApByrvqqmEY/mNDlIYRLEPz4MrzrdIwyouxrecWRgLt4CQLxHoiZA/HO+IUq3DjSKZqWWWVaOQl7F/8l5WeMtx2HNszk+zGLVxxZbP7x+xdwsuPX3UZr6p7pIuliekOXhEZAJLLWAE243+werPpT1l1BgAbX1nKeZa3kZ29m9sVe9tVgKYjfBGynmuS6HTPt+IA3xodR2dwAo/gs3+TW+/M61nd5q6jPH5U7QvuQmgkilzlsJXuZZSHU9pVK8cHeSVpPcMq2cRHP+nkyaVZahxbvITsM/NYeVzbxT4EABVHWZmY2sfxTGP1dU4e1HlkwfvYj9676dfJbv7u7ztFyAc+SHZ2D6uxq152Vx/PLfcoqev4gRbNsm9mqqY4ZQw2zie7YjorIhN9rMQEAFzNK4Nn3ioQJ9NnrIMzjIDJBTRNQESSAF4EUIEhn/mBqv5eIJUbxgQzpKIs/WhJKfzMOjijLBmaBxfYEOUggFtVtUdE4gBeFpF/VdXSvzobxqWD735mHZxRlgyF6grm9lVVBXBuzC6e3yzUs3HJEMRE71L4mXVwRtmS9W+aQKOIbBpmb1DVDcMTiEgUwGYAiwD8taq+7lflhhFqxDeRSeB+Zh2cUZb4PNG7XVXXjlifahbAShGpB/BjEVmuqjv8aoBhhBmffoML3M8C7eA0CmSqz8dru/L6Q3R8x9b5ZEcOu0rE3kWsrIzn+M0itYRVlbkez1LUAJLH+bSrWjlu5JmPuHEkaytZEbX9wByyNcWKPom5MSF7e1m+eOgBTnPye8ucPP/3S39J9pe/+kWy227mL/jk5by6MQDkUny+8Xmsduvf4cbA7POEkRTP6aSaWXkXr3QVr90DBSSsPjEUqiv49zNV7RCR5wCsBxDKDk5yWUQGzit2M5s20vHEVaw0zs1yY0ImT3g0r54VvOMHPat3A0B1LZnpRvaR7hjfZw0HnnKKyPX3cVsXLuQE8YRbb5bVi5EqDgy7ePMjZPff/RmniEP/7b+TXflH7Hcz33vZyaMHWPGJBLctevwwH1/Mq4QDQFXncS7To3iNtrlKUwyy/+aqKt00PjIRobr88jObSGSUJQpBVv3ZRkNEpuffKCEilQA+DGBPiU/RMC4pSuFnNkRplC0BTvRuAvBI/veBCIDvqerjQVVuGBNNQF9wvvvZqB2ciMwF8I8AZmJoZGiDqn5DRH4fwBcAnJsB+ruq+kQxjTGMsaIqSAc00VtVtwFYVco6zM+M8CKBzIMrhZ+N5QsuA+DLqrpFRGoBbBaRp/PHvq6q/8PPBhnGWFAA2cm1XI75mRFOJnMsSlU9AeBE/v/dIrIbwJyRcxlG6ZlMy+WYnxmG/1zUE0JE5mPoE/Lc3IQHRGSbiDwkIq4UbyjP/SKySUQ2ZXt6CiUxjItmaKJ31JctbBTrZ6c6zc8MPxFINFr0NhGMWWQiIjUAfgjgt1W1S0T+BsDXMDRa9DUA/xPA57z58hP5NgBAxYJmRe15Ofmxbg6cOvfKVrI7H/Vo1QGka7jJg9P4wtXt90wbuIOXhAeA7FGut+Pfs7S+5pkGJ8/gVJ6yUOF5NYgs7yI79pIbWLVxJ081OP0Ay317mt1pEb/8nd8kO/MRLiPSydcjvb/GKSM7hWXU6QqeBlHFlx3A0JSO4fTNYjvaxpLoNMevHmrr5mp3p08ogNzkGqIE4I+frVk0T9Fz/n6M1fG9mHlnF9kDt9zrtCNRy51krPo02b2NC5w81Zue5B3Tm8mc+9JDZPetuc0pI97P/prLeQIY73MV4/1X30z2yWqeWtDy0j+QnTzL0nwAmPelL5Ad2fk02VrrBnnWuVyP9PIzQFLsq311TU4Z4jm/ZCc7Y26qJ8g5gMjpk2SnF6920hhDjKmDy8cF+yGAb6nqjwBAVU8OO/73AExVZgSIIBtQsOWgMD8zwshEzIPzi7GoKAXANwHsVtU/H7a/Kf+7AQDci5BOejUmJ0MTvcM3vDhezM+MMDOZV/T+AIBfArBdRN7O7/tdAJ8VkZUYetYcBPBrJWmhYRRAVSbbEKX5mRFO/ItFGThjUVG+DBQcC7K5OMaEMdm+4MzPjDAzmb/gDCOEyGSbB2cYhs8E28FlBJHT59V3PUem8fGVrNTKuKJC7PjS35C9+IX7yI5v48CjfVtd9VP6Cg7InPgZqyb7XLETKk+xnbqRlZeDhzjQbP9lbrDlxrvbyG74U1ZIpa5zX+BTDRxMuWYnqxc//6v/SvZfbLzdKSPazX/mlCf4cnWPu+RS52JuS7aKzyeXZLt6jxtYOXJjh7PPL4ZUlOU5bFJqNBqDTm08b8+aS8cju98mO57qhZcd9/8u2at/59NkDza5gYMrl3AQivhhDkbct/pWspMdJ+AlVTud7Ipdr3KCOS1OnqpWDgzdvPcxsg/f9VtcxJltThmxbn72DMxbSnbPQ3/r5Glcz+ejVfwMkASrKlMx94FWd/o9socHyR7KxEprAEi1LCE7vn2jk8ZvJu0QpWGEkXPz4AzDKC2TWkVpGGElwGDLhnEJI4D9BmcYwaHq64rehmFMQqyDM8oShSCTsyFKwyg5AkQmKNRWsZTnd6dhAMjmo5kUu42GiMwVkedEZJeI7BSR3xo1k2EYF0Up/CzwLzgZJr6Ls8gImSz3t70tHKcNAJb8w2+Qfe3tu8l+c9mVZFdc4cainF7dR/aJa/l4Lus+9Lpne/ad4DiLc5ZxfLjW7W5wxpPPcmy+gbtYiZhgIRcAINnCF6lnKqtE//6f7iS7usDzuuIs25mFHCOvfZ37dva5VazMemgjx/uL9nCeXIE7qaGq393pEwGrKAsuZaOqu0bLOGHIeV/KJDkWZdzzNl5x6pCTfcVfPkh2//NPkd3QxH4HANjP+zK97GdV2dfJRoGvguQpT5zIRg6CmtnrBnKJLrmabL2RlcQth57jMmo96m0AOMbXINnNz43Ir3zeyZLy2IPJerKrD7NCcuquF5wyzr7C12TqbevI9iozATd+Zc5znf0nsInevvuZDVEaZYogE9yCpxdayia8HZxh+IUgEJFJKfzMOjijLJkokUmBpWwMY9IT9DQBv/zMOjijbPExFmWjiGwaZm/ILz9DeJey8atyw7hECNzPrIMzyhKFIONfB9euqmtHSlBoKRvDuBQQCER88bXA/cw6OKMsCVJkcqGlbAzjkkAABDBEWQo/sw7OKFsCXC6n4FI2qmqR/o1LgoBWE/Ddz4Lt4CJAtvq8NL75zqN0uPXHHEg12uwGAY57YpG+sZEDjyY9kvjqH7FEGgBy/Sy9jS3nP95Ac9rJU781Tnb39SyBH/g+y5mza9wpDqk0q/5kxiCXkeBAygDQ8CQHi87O5uPe69Ezz71m2Qp++6r6KcuZdY17vt984yaup57bmh3k6QoDl7llHD1eQI7tE6q+DlGOUtcFl7IJJaI5yLCgvfL2m3R84LZPkp08w34IANkKngaTvIGniaSr+R4CgK4buNx0NEn29HaeRhA75dbbO38F2dW7Odhyz7pfcPLUH9zM5Ub5sSbtPIUnnvYK/IGuNevJruri6QqZBF8PAKg8fYTsSJp9pPcaLrP2wBanjKkf4uuKbg5QLhV8DQEgfnw/75jT7KTxmyBEJqXwM/uCM8oWW03AMIyRsA7OKEsUQCZngXgMo+SIQMo0VJd1cEZZohD7gjMMY0SsgzPKllz5/CxmGOWNLZdjGMGhakOUhhEEIoIhBX/5EWgHF6/IoGlB+/t2fYKXY393IQcfjnW7D7D6W1vJPr2R1YsDKzzqxkZXhaQeRVC8pZvsaU+6AU471nG5sTirJM/cwueyZgErrABg89sLyU7uYSVidiGrsABgsI7Hvivb+Hj/dLaz012FWLaR7VhPBdnRyoyTB+2cBqeryKw6zdcwPdutt+KVGrdcH7EhysLo4CAyB88H+s0N8t+m8tQBsnOV7v0eeeNnZGdWs6o2sW+rk6dhJkcLF/Uoeo8fJLNz1R1OGXU7nucdGb4363d6jgMY3M+qwooVq8lOz+cA7PHjHAQZACoGWL04UMOOlexthxc5w84Y8z5XKjz3/4AbfFynsnPqFFYep2sanDyJk8fI7l9+k5PGd+wLzjCCw36DMwxjNEbtli+0Ro+INIjI0yLybv7fqaVvrmGcJ6sRX7YwYH5mhBmJSNHbRDAW7z63Rs9SANcD+KKILAXwFQDPqupiAM/mbcMIBNWhIUo/tpBgfmaEE5Gh9QWL3SaAUYcoR1ij5x4A6/LJHgHwPID/XJJWGkYBNDydU9GYnxmhZoK+wIrlon6D86zRMzPvlADQCsBdwtowSoYgO0lVlOZnRtjwaTWBwBlzB+ddo2e4bFRVVUTcIIhD+e4HcD8AxOqnon3zef/s7GVfrfWs/FPzMVZMAkDrdo9/L+Hl2humcHDGKTNd9dO9TW+T/WevcMy4qEd1CACRw6x4FI/gMTeb1V5vvb7ILWQax2v8xE2vkf30X37AyXJmBStLozNYiVX5OsfIi2/zqB8BpKeMbMtxV2ka6+c3tkwV/3lTnlCEFa+5iskb/g1f5x1fd5KMmyBXEwgSP/xs7sxGRK46vypJJMl/m94KvgGSLz/mlBddcjWXf5DjSGY7WXUIALmTHPOxc+9BshvvvI3syj7XN3Oz5rGd4Hsz1s4KQgBIXHMj7+hkNWf/c98lu/e+/+CUUX+EVaEVHoVk/5LrnDyZhRw3MzbAD7C4x841Njll5CpYnRwZ5OdZvL/TyTO49Aay9UePOGmMIcbULV9gjZ6TItKUP94EoK1QXlXdoKprVXVttNoNWGoY40KHfofzYwsLfvlZY70bYNwwxs255XKK3SaAsagoL7RGz2MA7sv//z4Aj/rfPMMojGLSqSjNz4yQIpBIpOhtIhjLEGXBNXoA/DGA74nI5wEcAuCuY2EYJSNUCkg/MD8zwstkjWQyyho9t11gv2GUnFwusBW9HwJwN4A2VV1eijrMz4zQIggskonfvhaO8RnDuEiGfj8TX7Yx8DCA9aMlMozJieTnwhW5jY2H4aOvWaguo2wJaohSVV/MS/cNwyghfvtaoB1cpDKD2hXnJbxnTrLaa968U2Qf3zzbLYNV85hax9MCuvpYVtzZx/J+APjz7R8lu6KLP2RTBURo19zCMumt/8IBXCXKcrxchaehAKa+niD7O4MsPY7eViAY62mW/ct+VqKmP8CBogd6uA4AqJ/G16jjUB3XkXClhNkZ3P6a7Vxu/xpua88cdzDgmVdWOPv8JKghyrJjoB/Yc172npjOU2siRw6xffU1ThHqGZLKnT3LeQooor37pn2SpxpkPUGdY32eeUEABl9+juzoHfdwgiwHOQcASXGg8+5FfD5T4h6f2PasUwbqOchxrvkyspPbX3HrreHpF7kzPD0h0jyfM6TdYOqRDp4qMdDCo3LJdzY5eZKxo2TrB29x0gzplXxCAImW57dQebbauORRjHl4cSw0isjwJ8kGVd3gV+GGYQCYAD+zDs4oW3ycwtauqmtHT2YYlyK+zWML3M+sgzPKEwXUhigNo+QIyjdUV3m22jAQnIpSRL4N4FUAV4jI0fycNMO4NAgwkonfvmZfcEbZElSYLVX9bDA1Gcaljd++FmgHl81G0Nk1LLhoP39Atr7GqsnEMjfQaN8JVi71/YyXlh+Y71FZFXhDn7eMgzgfa+fIwTUbOQAqALy6l1VVken8dK3ZHSc7cz2rGwFgoJVVZC0/5jIW/+E7Tp6f5S4nOz4nRXZjLSskl7a4AaqfenEV2VrHgaEl5X7IL/nKe2Sf/AVWjabfYXVqdi4HkgaAXL27zy9UAZ2kqwkUi0SjiNQOkwIn+X6W1RycWPbtcMuYwYGBB67luebJU6zELERm93ayY9NnkN271BMkGUD10qVka5dHZTiX70MAqNjJQcuTU1k1euiKO8lu/NbX3HqXeVTRJzmoc7argOJz336yq9Z55uP3eAJSe9WcAF5s/hzZq+IcoDzWcoWTJ3byMLe1231O+otM2HpuxWJfcEbZEqZAyYYxqZmsoboMI7RYB2cYwTBBwZKLxTo4o0wRU1EaRhCIDVEaRrDkY1EahmFcCOvgjPLFhigNIxgmaMHSYgm0g6uIZ7Bw1vl4k0d28/L0A/NZdZfqcONIVh+Mkt3TwjETY918fM0H9zpl7Po+K5NmrD9J9oklHP8RAKbNYBVVz+FGbiuHd0RsCysmAaDvco5Fd2gmKy+PP1MgdmMLx3zsbR95VfTnOhc7+3L1rJpcsvA42e8cYdUZALR9ilVlAx/m8x9s9yhNo27szWjC3ecr9gVXEE2nkT5x4vyOBaxMjJ84wBnqpjplDMxYQLZXNZmrZDUzAKQ2vsBp7vw0J9j4BJnVxzi+KwDk2nnB8txMfkbEB1w1Y/rKNWQnjrDPt5xl/87d9hGnDBw/SKY0sH/zU2WIqql83aTrDNmp/axETsxrccpYGd9Gds2WZ0ZsBwAg51GKp1JuGr+xIUrDCBj7gjOMYDAVpWEEiIXqMoxgEDEVpWEEjn3BGUYw2BecYQSM/QZnGMYIWAdnlCcKSIk1LIZh5DGRyegM9iWwf8vc9+3sZaz+kS5uTrLNvaiRjGdHnJ9yUw5wns0Lmp0yvNrMZMwTM7HaXTW4/xWPmmk1x5pMdbHyMvqeG3euch+nWfRhjmV34hFWrgFAewMrLadu42vU28zyzUgBQVU1h6vEOz1zyf7gdbucPC+kWWkqvXw+K65kVd3epzlWJwCkr3RXKPcPsS+4C1FZhdiK88tuyXG+z1DFCsh0PceIBACNeHSDGfaRnmnuvTplPqsz+7xlpj3OO+DeH5mVHyA7vncL2VIzBV5ys/neS89ZxPW+9BTZvXf9ilPG1E5ejbu7hRXN1fW8ijYA5GLsE5kEK5yT1ayk7nvVXRV8SszzCK7iMgZ37XTyRG5hFWj8gOu/vmK/wRnGBGC/wRlGMNhvcIYRMDZEaRjBUKZDlKO2WkQeEpE2EdkxbN/vi8gxEXk7v91V2mYahgfF0BClH9sYEJH1IrJXRPaJyFf8Ph3zM8Pw38/G0i0/DGB9gf1fV9WV+e2JAscNo6SI+rONWo9IFMBfA7gTwFIAnxWRpSPnumgehvmZEUokH3C5yG20WkrgZ6N2cKr6IoAzo6UzjMBRn7bRuRbAPlXdr6opAN8BcI+PZ2J+ZoQXwZDIpNhtdHz3s2IGVh8QkW35oRU3mF0eEblfRDaJyKZcb++FkhnGRePjF1zjuXs0v93vqWoOgCPD7KP5fUFw0X7W3umuJm8Y42Xo1wApesME+Nl4RSZ/A+BrGDr3rwH4nwA+Vyihqm4AsAEAqmbO1eoj5z9Vv3T345T2Gxs+SXbajVeM5T/PAVpffWch2V2Xsbw5utcNTtx9GasTug+zTDp2iqX5AJDxxBauf5Sl1h2X8yd4zY2n4KV93zSyD/+A257hwwCAOU/zO8ixdR5lRRVPaUgedtt++cf3kb3tNZZV7/y7ZU6epn7+tOlcyOXuaOW2z7qp1Smj+kG+9vudFEXi3zSBdlVdO3qywBmXn61ctkT7p52fCtLzne9T2im//iWyo6kCL55PfJftK5eQWdPu/jUzLZymqpXvO7TMJzNXP90pIzrIbTm99mNkTz3tKRNA5K2XuYyFl5Pde8cvkF3Z734on7jiVrKb3nuJEwx4Jz0A2VnzyZZnfkx27lqe8jD4qd9wyuiO8aSlqZ0HyY5PcwOh5zZz23bd+h+dNMB/KrBvwgncz8bVwanq++G5ReTvATw+QnLD8B9FkCrKYwCGTx5szu8rKeZnRjgQIBKI4N53PxvXEKWINA0z7wWw40JpDaNUBCUyAfAmgMUiskBEEgA+A+CxUp4bYH5mXHL47mejdssi8m0A6zA0fnoUwO8BWCciKzH0Hn0QwK8V0wjDGBcBfcGpakZEHgDwJIaWBntIVd0QE0VgfmaEGQ1goncp/GzUDk5VP1tg9zeLqdQwiuUivr58IS/RL5lM3/zMCC0igU309tvPLJKJUb5YLErDCAYL1TU62QTQ23z+tfuPttxJx6e38it5b4EFLV/dtpjs6BQOAnvNzXvIfv0NDhoMANFBLrfiGAdN7Z/tjn0lFneR3VbHEs+6lrNknzriKrrr9vFbUPd8Pl9vuwDg7GLOEx3gPPE2VjcONrpt3/99Dj6LG1gRdqrODQwtCY86s4ajOCff5PM/esSVgEZ+yROw900nSVHYagKFiWRSSJ45Hxy46tYb6XhbNSvzaiLtThlVK1byjh6+/wdfed7Jk7zuBrI1kSQ73ciBzxOnXf2AHuKgxo09nWRF+RFUAAAa0klEQVTnjh928kTmzCO7dybf71XtHBhc4+79Pk35fs9VsLoxO9VVM8a7+Lr1rf802RW7XyN7ak+HUwbS7Ffa08OHl17jZEk08/kuPfITt1y/sWDLhhEwFmzZMIwRsA7OKE8C/g3OMC5dJBCRSSmwDs4oX2yI0jBKj6BsVxOwDs4oW+wLzjCCQcu0gyvPVhuGYRjGKAT/BTfsrTsS5TGmdl4lHlVLWJkIAMktrE5Md7FS7/VWjoeXOOuOHafq+dW/v4nbobUZJ8/MKRzA9uSmOrK7U9yuZWsOOmUc3L+A7KoT3Lbeue6YWyTF7yCfW/8zsh959DayNeF+1mQ+xEq0+Fvc9tpr3Nh82ecayE6eZuXZ6Tv6uYy3WHUGAJXt3JaDTooiUFNRjhnlC9V4Yjsf38/xXQEgvZRDBkarp5CdnN4EL5ka9oFYL993ibMnOEMfKwYBINPBedSjIox7lJkAkNryOtc7i+OkDtaxAnK4wvQckRjf352PcQCNKT/3KSePVwGZ3MK+mb5yDdnRHW84RaRWf4js3ipWI0/b+pSTZ2DRKrL7qhrdtvmKQCPR0ZOFEBuiNMoXG6I0DGMErIMzyhfr4AwjGExFaRjBIbAhSsMIhABDdfmNdXBGeWLz4AwjEM4teFqOWAdnlC/WwRmGMQLWwRlliw1RGkZA2BDl6MQr05i14v1FinH2hVl0fLDBE2z5nXqnjOgylhZrmuWrTT+q4DJmuZ/W/S08DaDxNQ5YnP5Yr5OnrZuDCwvHZsXMZW1kH/oXnhIAAD1LODD0L17DwVif/MZNTp4cNw0bXr2F7GqP0npwhvtZM+eP+OZ85zdY3hxJF5AA38Ry7c6dPLVAPYGwe+Z7LgiA1LU8lQD/x62mKELwBSciPw/g9wFcCeBaVd00sS0CMNCP3O6t75uZa9bR4Xg3TwvRBW5A8vh7nrVVY/yoOLH6HidPbf8pLuMkBznuWHQ92VNec9eyjE5hP8t4HqzZPducPLlbP0F28hgHXO988RWy+3/1y269OX4mTL31g2SnktwuAIieZZ/fc8MXyV66+9tka9zjzAAqtr9MdnzRck5QIMhx8hRf1+Rpn6OYF0Ax8UOU4/E1+4IzypPwzIPbAeCTAP5uohtiGKVBwhLJ5KJ9zTo4o3wJwRecqu4GACnTH+ENY0yEoIMbj69ZB2eULaaiNAxjJKyDM8oThZ+rCTSKyPDx/A2quuGcISLPAJjlZsODqvqob60wjBCiIsj5E6prRD8D/Pc16+CMskTym0+0q+raCx1U1dv9q8owLllG9DPAf18LtINLD8ZxbP/09+3INM8Yk+eJNe9JN+hxd3MN2T28ejtO3MRlVrlxVVHd0Ef26bXVZE95joPGAsCg550issaztPz3ZrDd4tZ7+WUcbPaxh2/mBG616F3DSsSlc06S3fkUX4C+Oe5Y+Tu/xOcXr+Iy+3tZeQoA2sWKr7jnBa6unq9hz1EOzgwAVS0pZ5+v2BBlQaSiArH5l71vq0c16Q2+fHguK3MBoH4mKytrOo6QPevQq06ewYa5XM3Z01zmflb79a2+1Skj2dlKdmLvFrLPrvu0k6e24zDZ6X3vkh3/t/eTHRnocOt9dzPZqWPHyD69xH3uNrXzw2XpQY8qdIB9RKrYDwEANRzEWnKsRs51um3FjGa2+w+6afymTH9jnvhfDg1jnEjOn62oNojcKyJHAdwA4Cci8qQf52YYYUIlUvRWLOPxtVFrFZGHRKRNRHYM29cgIk+LyLv5fwt8exhGiVGftmKaoPpjVW1W1QpVnamqHxlvWeZrRjgRqA9bsYzH18bSrT4MYL1n31cAPKuqiwE8m7cNIzjysSj92ELEwzBfMwzfGLWDU9UXAXhXxLwHwCP5/z8C4BMwjIAJwxCln5ivGWElDEOU42G8IpOZqnpOMdEKYOZIiQ2jJITr66tUmK8ZE4ugbEUmRasoVVVFLjzQIyL3A7gfAKIN9dDY+VdmbwzE3FxW9x2+01X3rVrLCqkjf7eI7FPXcFP6CzwOsl2VZGuM82TdalHL4d/Q1cJvJOkavgFinhiRAPDunjm8YzErpiTj3kTRw9zWA3vnkz14M3+CxHrcN6UIh8BEqtYTE6/Any9xmv82C27mC7C/rZHszCxXMdm5340l6ichG14sOSP52nA/mzu9AcieVyBrlN080sqqwxZ9zikvtfkNsjvu+TWyG7vdMIAJjwJSpnj+/h6FYCwz4JTR28Cq4NoTfN9VpF3HylSwsjq5ZCnZ8RPvcIaYGxMyN4vrlZYlZDcd3OjmqeR61VNutN8T0zbrxmvNTpnG9usvkp1oKjAl7AwrqdFymZvGVwRapnrE8bb6pIg0AUD+37YLJVTVDaq6VlXXRmsLyGQNYzycm+jtxxZuxuRrw/1sel1NoSSGMS7OrQdX7DYRjLeDewzAffn/3wfAojkYgSKYlCKTQpivGRPOpP0NTkS+DWAdhsKsHAXwewD+GMD3ROTzAA4B+IVSNtIwCiG58PdOF4P5mhFWwrBczngYtYNT1c9e4NBtPrfFMMaOD3PYwob5mmH4i8WiNMqWMhheNIxJQGjWg7torIMzypYwzWEzjMnMRIlEiiXQDi4Sy6Gm8XwA0oo36uj4mdoE2S1PurLa7bObyF7zG7w8fddxDkQ6cLLKKSNxhOuJedS8KY5/CgDob+KnaW6QL13t3RxIOZN1l5dIb+KAzNkkf4LUL+XgtADQfpyv0dSXud6BBRyQespOPjcAwMe53PQzLE3uvryAfLmS29b7Db6ui36bg+/ub+cyAWDuN7ltB92WFYd9wRVEMxnk2s+LLbsXXkPH6/q6yD7css4po+XkcbJzP/zfXMdcT8BfAJHpPCcn6wkKnK1gFXWsn9sBAPEOnmqAiiSZiZced/JIlH0tezWfr6Q80xH27XLKiMyaTfbZxTxNYNqJA06ensU8HaHmVQ623HfNh8mu8k5XKNC2Ux9/gOzpj/2Vkyc+YzrZ7y4t7c+yQ78GWAdnGMFRHgpIwzAmEOvgjLJEYEOUhhEIIsiJLwueBo51cEb5ovYJZxjGhbEOzihbbIjSMILBVJSGESQKiKuNCRwR+TMAHwOQAvAegF9V1QLLMBtG+RIGkcl4fC3QDk77o8hsPa8KHLjC8wruMdvWuEFRM0e4yWems0oy5VE3asL9oSZVz3+s1FSuODLovq0kT/K+5KJuso+3cWDZ2tc4SDIApFZx1OOKI3x+p1tZMQkA8VoOYrzqizvJfmonK7mu/cIWp4znH1tN9g2f3Ub2CxuvcvJcfg0HuT26mM/vlFc1ubPWKePIhz07XnKSFEc4vuCeBvBVVc2IyJ8A+CqA/zyhLUpWIbdk1fvmlJMe9Z7nbXz2me1OEdrEwYejJznAr1QUiEie4fs72n12RFsTrJAEgHQdK41jBzi4emymGz2954rrya7Zzz6QmcnnEpteIAJ7Dys6k//8DT6+aqWTJfq9vyU7+9FPcoLH/olMvfEmp4zMWxzUuukg/63Eo5gEgOzCZWQvPP2ak8ZPNDzz4C7a10LRasMYD2GIRamqT6nqufkQrwFw9fOGYRTNeHzNhiiN8kRDGYvycwC+O9GNMAy/CcMQpYcx+Zp1cEb54l//1igiwxc426CqG84ZIvIMgAILc+FBVX00n+ZBABkA3/KtVYYREnyKZDKinwH++5p1cEZZcm65HJ9oV9W1FzqoqreP2BaRXwFwN4DbVG3ugjH5UPWlgxvRz4bq8dfXrIMzyhPVUAxRish6AL8D4BZV7RstvWGUH+FY0Xs8vhasijIKpOuGPZQ8r+DVh3m2fIRFWQDcmJBnHmaFlK7mMiXuPgTrWlhZ2r3fo4A86L6tpD0iQX2cVYQ1HkFY382eAJcA6l7mWHwdK/gEq+r7nTzzv8L7XvhFVnMtvvkw2T/dvtwt43VWYm6MXU12pdtUvDsw3905jGw1/x1iBe6kqlZ3n69MfP8GAH8FoALA0zI0jPOaqv76hLYol0G098Lq6cHGuZw86qqV42c4tmr3Xb9K9rQjb7kFe1SUueN8b8q8hWT3Nba49Q6yOrn3hrvJjmYGnTw1O1me27uM1YrVB7eSrV2dThlbVn+J7BUtPyM7/foLTp7q1avIPtjAftV8O8diTSXcuLjxNa6SdDgy4DpnJMvXub+uyUkzSbloX7MvOKM8UUCyE9/DqeqiiW6DYZQSBZALwRfceHzNOjijfJn4/s0wjBBjHZxRtlioLsMIhhBOExgT1sEZZUsYRCaGMfkR6+AMI1AUNkRpGAHh0zSBwAm8g9PI+adSooN/uMywyBDCIqShfbWsIIr38QrW0ZmsOqxMulLMzlMeSWQFPylrjrvxK499iNNkVnE90bdryM4ecxVTgyzWREUrq9f6o+4Te/eDrLKKdHDb9m9hRVxklmf1YgC5/+SJAXiWlyxvnu6uJP7ONi53xpt8g59Zyn+7XAG1qt7uUfL9LyfJuBmaB2c9XCG81yZTzTdeNMUK60i0wGOgt4fMdMQTe7LdlcjmBvjeizQ0coIUKyC7KjnuJAA0Hd9LdrzdE1fyclYuAoDOmEN2op/vu2wDx56MZt0o3WvefZjLrPXEhV1RYPrWab4GzT/lGzzWwErrnCeeJwBErmJVdPtcjhvbcIqvBwBHrVq56Wk3jQHAvuCMMiYMKkrDmOwMDZbYF5xhBIcNURpGYFySHZyIHATQDSALIDNaGBbD8A+9pFb0Nl8zJpJLsoPL8yFVbfehHMO4KC5BFaX5mjEBiIlMDCNQFBBXC2QYhvE+xcZfUQBPichmEbm/UAIRuV9ENonIpmxPgaCHhjFeVP3ZyoMRfW24n53q6C6Q3TDGx1CoLil6mwiK/YK7SVWPicgMDAXA3KOqLw5PkF/vZwMA1C2ZqUtWnA/AuucIL/sjbSxFbnzbrfDUYra75nEfne7iMrJtlU4ZiSaWSQ92cp4T97rzEyJtLNdP9fL0hEgjPyjrd7t/0G5PbNnm5zkI8rEvsA0A0a08/aDCG0PX83xOn3TP98jVnrZ48rx30iPnBqCeKQvpz/BUg+SzHgl0wj3fxdN4NG27k6I4LrEhyhF9bbifrZo7U1PbzztPYi5P+dBp7HenZ1/lVNZ45F2y63uOc4IanmoCAJEGlv3rKQ7YLFN4ukLT2//ilKGeMqSap/TEuk45ebpnXclNO3uI7EOzrid7waF/cspIL15B9mCSpwmouN8C8TqefuCETfbkSTQVWObMM2Wh4aXvcTvW3uZkiWb5OaGnSj9qXa6/wRX1Baeqx/L/tgH4MYBr/WiUYYyJS+gLznzNmDB0aKJ3sdtEMO4OTkSqRaT23P8B3AFgh18NM4wRGRo38WcLOeZrhjE+ihminAngx/l1eWIA/llVf+pLqwxjFAQKyZVB7+QP5mvGBCLI6cQvlzMext3Bqep+ACtGTWgYpSIEw4si8jUA92DoW7ANwK+o6vGRc10c5muGMT5fK89u2TDyC576sRXJn6nq1aq6EsDjAP5r8SdnGOHhXKiuYjcfuGhfC3Qe3GBXAgeenf++LdN4iCnRwRehfT0HNAYAHeAmD1zDUw8iHhVhyxNuYNXWL/BDrWEzBz2WDNsAcOZqbqt0cjsq5rE0u7/dVZlFPXGQj9zO9cR2sjITAObdzoqwfZvnkV2/h69Z3zoOkgsAkUMcxTo6yHkyNe5QXyTLaQbTfL69V7OS66qFR50ydj692NnnKyH4glPVrmFmNUIQQExqpkA+cPv7tnZzMO1MNSsEG7c+6RZSwZrA5N43+Hijqwg8OP9WsltO/iPZ3Qs4kHAu4j5+6o5s4x1etebxI06eyinTyc4mPM+AY6+Qnb5suVOGvvwU2dUrryG7c9YSJ0/tnufJzs1mmbTGPUrrgQLTpLzXIMZ25UFXe5x6bx8Xcct6t1z8VYF94ycME73H42s20dsoU3xVQDaKyKZh9oa87H5MiMh/B/DLADoBfMivRhlGWPDp1+6i/Ay4eF+zDs4oTxSAf6sJtI8U21FEngFQYBITHlTVR1X1QQAPishXATwA4Pf8aphhhAGfvuBG9DPAf1+zDs4oW4JaD05Vbx89FQDgWwCegHVwhjEu/PY1E5kY5UsIJnqLyPAfGu8BsKeoAg0jZPghMPFDZDIeX7MvOKM8UQWyoZgH98cicgWGfqY4BODXJ7g9huE7YRCZYBy+NqEd3GVXs/LuwOusEGx4xonuhrPL2M4Iv4FXneSP0gOfclWU9S9yfLtEF5dxern7x/RGrq/dz/V0C8eMrHEFoOhp8apGuYwp17lx9vYeaCK76jS3TaOcPnXWvWaxDOdJz2M555RNbp7OK/m69R3ma1b/juc671zolJGaXeIhxHCoKH9uotswGpntHNQ1uppjM569yo13WN+6m2yvR6TqZ8LL/D2Pk9234oNkDyT4HprWutNtbJRv6L4ZfF9VFZjcn415FJ+nD5OdqeYYmJG3NrrVLryM7FRtA+fJuc8R1E1lO8Jtj7ay4rNv8RqniKpj/BEizfPJ7pnpKpFj85aSXdFxwknjN2GIRTkeX7MvOKN8CUEHZxhGeLEOzihPVJ1I7IZh+I8qkA3HEOVFYx2cUb7YF5xhGCNgHZxRniiAS2s9OMOYMEIiMrlorIMzypdLZzUBw5hQynWwxDo4o0wpn8VKDaO8EeRCoKIcD4F2cBoDUg3nH0rvHuSILNEW1tYnNlcUKIQvdMVhDmg6sIzLaGrgIMgA0Bpn2XBvK5eRneOJigygYh9LkQdZRQyt4K+J5p+4y8ifvGUG2Z2L+QF9Znujkyfiift85UffJXvTrgVkS8a9EWev5RUlop45D2fQ7OSJTeVrkE2zBLrrBm77lI0c4BYAbr9pK9l/76QoAoWJTC5ELoPYsADLssAzheMEB/AemL3KKUKF76PsTJ7Ck9jvrreaPXOG7KpMhuxkA08tiLS5AbrTcy/nenrPeBJwkG8A2FXB8vtFTZ4pO6c4ODGudFce0mya7Z/xlIcpSz3zkwAgxs6Z2/Ym2VnvEHqBaQLo9Jyfp8yaDg6UDQDdS27kel54zi3XRxQ2RGkYwWNfcIZhjIB1cEaZoiYyMYyAKNd3SevgjPJEAbUhSsMIhDBEMhkP1sEZ5Uu5vlYaRjlRxoMl1sEZ5YmqTRMwDGNEAu3gIokski3nVx1Pp7n6dD8riKb95kGnjLNPsyIs51EZVlaxyqqj11X3Ve9m1WTcI7RcfBMHawWAt4+wuiu3oI/syElWWe79LxxYFgBmNp4ku+YnrCqb9UlWtwFA1yCXu3krn/+U91jdmL2p0ymj9dXZZHviUyM93309q91YzXlYEIeoR8wWudcNFP3CEys9e/7RSVMMNkR5AVIp4NiweynB9zuSVWROe/SvnCKyN99BtmT5Bsj19Tp5ItV8z6TmXkH2YMUUsuMbX3DKSMxitWbk2AGytdEN8rx61z+QnTnVRnb/TR/jep/5gVNGJMmK7Yqr+d4dmMnBmAGgYvvLZMtqVjdCOCB5Zbvr331LPYpIj2w6G/X87QDUvvRDsvXOe5w0+INvuvvGiQLI5WyI0jACxObBGYYxMkUteCoi60Vkr4jsE5Gv+NUowxiVc6G6/Nh8QES+LCIqIu5kxuLLNj8zJpRcfrJ3MZtfXIyvjfsLTkSiAP4awIcBHAXwpog8pqq7xlumYYwVRXiGKEVkLoA7ALhj28WXbX5mTDhhGSy5WF8r5gvuWgD7VHW/qqYAfAdDy4gbRulRBTTnz1Y8XwfwOxjqd/3G/MyYUBQC1eI3n7goXyvmN7g5AIYvWXsUwHVFlGcYF4WGQLssIvcAOKaqW0VK8kO8+ZlhYHy+JjrOb08R+RSA9ar67/L2LwG4TlUf8KS7H8D9eXM5ADeIXThpBOAGlAwn5dLWK1TVlZeOAxH5KYbO2w+SAIYH39ygqhuG1fUMgFlOLuBBAL8L4A5V7RSRgwDWqqpvfwvzs1BRTm0No6+N6Gf5unz1tWK+4I4BmDvMbs7vI/InsAEARGSTqq4tos7AsLb6j4hs8qssVV3vV1ljqOv2QvtF5CoACwCce6NsBrBFRK5V1Vafqjc/Cwnl1la/yipnXyumg3sTwGIRWYAhh/sMgH9TRHmGUVao6nYA7y8RUYovOJifGca4fW3cHZyqZkTkAQBPAogCeEhVd463PMMwXMzPDGP8FDXRW1WfAPDERWTZMHqS0GBt9Z9yaee4UNX5JSrX/CwcWFtDwlh9bdwiE8MwDMMIM0VFMjEMwzCMsBJIBxf2UEMi8pCItInIjmH7GkTkaRF5N//v1IlsY75Nc0XkORHZJSI7ReS3QtzWpIi8ISJb8239g/z+BSLyev5e+K6IuNFkjXETZl8zPytJW83PRqDkHdywUEN3AlgK4LMisrTU9V4kDwPwSmG/AuBZVV0M4Nm8PdFkAHxZVZcCuB7AF/PXMoxtHQRwq6quALASwHoRuR7AnwD4uqouAnAWwOcnsI2TijLwtYdhfuY35mcjEMQXXOhDDanqiwDOeHbfA+CR/P8fAfCJQBtVAFU9oapb8v/vBrAbQ5EuwthWVdWevBnPbwrgVgDn1isJRVsnEaH2NfMz/zE/G5kgOrhCoYbmBFBvscxU1RP5/7cCcBeimkBEZD6AVQBeR0jbKiJREXkbQBuApwG8B6BDVc8tLlYu90K5UI6+Fsp79xzmZ+WNiUzGgA5JTUMjNxWRGgA/BPDbqto1/FiY2qqqWVVdiaGoA9cCWDLBTTJCTJjuXcD8bDIQRAc3plBDIeSkiDQBQP7ftlHSB4KIxDHkdN9S1R/ld4eyredQ1Q4AzwG4AUC9iJybf1ku90K5UI6+Fsp71/xschBEB/d+qKG8kuczAB4LoN5ieQzAffn/3wfg0QlsCwBAhoKwfRPAblX982GHwtjW6SJSn/9/JYbWM9uNIQf8VD5ZKNo6iShHXwvjvWt+NllQ1ZJvAO4C8A6GxoYfDKLOi2zftwGcAJDG0Hj15wFMw5BS6l0AzwBoCEE7b8LQsMg2AG/nt7tC2tarAbyVb+sOAP81v38hgDcA7APwfQAVE93WybSF2dfMz0rSVvOzETaLZGIYhmFMSkxkYhiGYUxKrIMzDMMwJiXWwRmGYRiTEuvgDMMwjEmJdXCGYRjGpMQ6OMMwDGNSYh2cYRiGMSmxDs4wDMOYlPx/8+1S9yyHLIEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x216 with 4 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "viridis = cm.get_cmap('viridis', 256)\n",
    "\n",
    "def plot_examples(cms):\n",
    "    \"\"\"\n",
    "    helper function to plot two colormaps\n",
    "    \"\"\"\n",
    "    np.random.seed(19680801)\n",
    "    data = np.random.randn(30, 30)\n",
    "\n",
    "    fig, axs = plt.subplots(1, 2, figsize=(6, 3), constrained_layout=True)\n",
    "    for [ax, cmap] in zip(axs, cms):\n",
    "        psm = ax.pcolormesh(data, cmap=cmap, rasterized=True, vmin=-4, vmax=4)\n",
    "        fig.colorbar(psm, ax=ax)\n",
    "    plt.show()\n",
    "\n",
    "plot_examples([viridis, new_coolwarm])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def draw_triple_pdfs(dists, nlevels=200, subdiv=6, filename='dummy.pdf', **kwargs):\n",
    "    \n",
    "    fig, axs = plt.subplots(nrows=1, ncols=len(dists), sharex=False, figsize=(15, 5))\n",
    "    \n",
    "    for i, d in enumerate(dists):\n",
    "        \n",
    "        refiner = tri.UniformTriRefiner(triangle)\n",
    "        trimesh = refiner.refine_triangulation(subdiv=subdiv)\n",
    "        pvals = [d.pdf(xy2bc(xy)) for xy in zip(trimesh.x, trimesh.y)]\n",
    "\n",
    "        cs = axs[i].tricontourf(trimesh, pvals, nlevels, cmap='cool') #plasma, inferno is OK\n",
    "        for c in cs.collections:\n",
    "            c.set_rasterized(True)\n",
    "        axs[i].axis('equal')\n",
    "        axs[i].set_xlim(0, 1)\n",
    "        axs[i].set_ylim(0, 0.75**0.5)\n",
    "        axs[i].axis('off')\n",
    "    \n",
    "    fig.tight_layout()\n",
    "    plt.savefig('figures/{}'.format(filename))\n",
    "    plt.show()   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "mu1 = np.array([0.5, 0.5, 0.5])\n",
    "Sigma1 = 1*np.eye(3)\n",
    "dists = [Normal3D(mu1, Sigma1), Normal3D(mu1, Sigma1), Normal3D(mu1, Sigma1)]\n",
    "draw_triple_pdfs(dists)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# take subset of mnist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/pip-req-build-58y_cjjl/aten/src/ATen/native/IndexingUtils.h:20: UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "18623\n",
      "tensor([0, 1, 2,  ..., 0, 2, 1])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.image.AxesImage at 0x7fcb57fa19e8>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "MNIST_transform = torchvision.transforms.ToTensor()\n",
    "\n",
    "MNIST_train = torchvision.datasets.MNIST(\n",
    "        '~/data/mnist',\n",
    "        train=True,\n",
    "        download=True,\n",
    "        transform=MNIST_transform)\n",
    "\n",
    "def get_subset_MNIST(classes=[0,1,2], dataset=MNIST_train):\n",
    "    \n",
    "    dataset.targets = dataset.targets.clone().detach()\n",
    "    idx = torch.zeros(dataset.targets.size()).byte()\n",
    "    for c in classes:\n",
    "        idx += (dataset.targets==c).byte()\n",
    "    dataset.targets= dataset.targets[idx]\n",
    "    dataset.data = dataset.data[idx.numpy().astype(np.bool)]\n",
    "    \n",
    "    #remap all classes to list of ints starting at 1\n",
    "    map_dict = dict()\n",
    "    for i, c in enumerate(classes):\n",
    "        map_dict[c] = i\n",
    "    \n",
    "    for i, t in enumerate(dataset.targets):\n",
    "        dataset.targets[i] = map_dict[t.item()]\n",
    "    \n",
    "    return(dataset.data, dataset.targets)\n",
    "\n",
    "num_samples = \"all\"\n",
    "classes = [0,1,2]\n",
    "MNIST_train.data, MNIST_train.targets = get_subset_MNIST(classes=classes, dataset=MNIST_train)\n",
    "print(len(MNIST_train.targets))\n",
    "print(MNIST_train.targets)\n",
    "plt.imshow(MNIST_train.data[0].numpy())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3147\n",
      "tensor([2, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 0, 1, 0, 0, 2,\n",
      "        1, 2, 2, 1, 1, 1, 0, 2, 1, 2, 0, 1, 0, 1, 1, 1, 2, 0, 2, 1, 0, 1, 2, 2,\n",
      "        1, 1, 1, 0, 2, 0, 1, 1, 1, 0, 0, 1, 2, 1, 1, 1, 2, 0, 2, 2, 1, 2, 1, 2,\n",
      "        2, 1, 2, 0, 2, 1, 2, 2, 1, 1, 0, 0, 1, 1, 2, 1, 2, 2, 1, 2, 2, 0, 0, 0,\n",
      "        2, 1, 2, 0])\n",
      "6853\n",
      "tensor([4, 1, 1, 6, 2, 6, 3, 6, 2, 6, 4, 0, 1, 6, 3, 3, 2, 1, 4, 1, 0, 0, 1, 4,\n",
      "        4, 4, 1, 0, 2, 1, 1, 3, 0, 2, 2, 3, 1, 6, 2, 4, 5, 6, 0, 4, 1, 3, 1, 0,\n",
      "        4, 6, 4, 0, 6, 4, 4, 3, 4, 5, 1, 4, 0, 3, 0, 3, 6, 0, 1, 4, 3, 6, 3, 2,\n",
      "        1, 6, 6, 6, 1, 5, 4, 0, 6, 4, 1, 1, 1, 6, 2, 1, 4, 3, 4, 6, 2, 5, 2, 3,\n",
      "        3, 2, 4, 5])\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/pip-req-build-58y_cjjl/aten/src/ATen/native/IndexingUtils.h:20: UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead.\n",
      "/tmp/pip-req-build-58y_cjjl/aten/src/ATen/native/IndexingUtils.h:20: UserWarning: indexing with dtype torch.uint8 is now deprecated, please use a dtype torch.bool instead.\n"
     ]
    }
   ],
   "source": [
    "#get an in test and out test dataset\n",
    "\n",
    "MNIST_test_in = torchvision.datasets.MNIST(\n",
    "        '~/data/mnist',\n",
    "        train=False,\n",
    "        download=True,\n",
    "        transform=MNIST_transform)\n",
    "\n",
    "MNIST_test_in.data, MNIST_test_in.targets = get_subset_MNIST(classes=classes, dataset=MNIST_test_in)\n",
    "print(len(MNIST_test_in.targets))\n",
    "print(MNIST_test_in.targets[:100])\n",
    "\n",
    "\n",
    "MNIST_test_out = torchvision.datasets.MNIST(\n",
    "        '~/data/mnist',\n",
    "        train=False,\n",
    "        download=True,\n",
    "        transform=MNIST_transform)\n",
    "\n",
    "classes_out = [c for c in range(10) if c not in classes]\n",
    "MNIST_test_out.data, MNIST_test_out.targets = get_subset_MNIST(classes=classes_out, dataset=MNIST_test_out)\n",
    "print(len(MNIST_test_out.targets))\n",
    "print(MNIST_test_out.targets[:100])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "BATCH_SIZE_TRAIN_MNIST = 64\n",
    "BATCH_SIZE_TEST_MNIST = 32\n",
    "MAX_ITER_MNIST = 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist_train_loader = torch.utils.data.dataloader.DataLoader(\n",
    "    MNIST_train,\n",
    "    batch_size=BATCH_SIZE_TRAIN_MNIST,\n",
    "    shuffle=True\n",
    ")\n",
    "\n",
    "mnist_test_loader = torch.utils.data.dataloader.DataLoader(\n",
    "    MNIST_test_in,\n",
    "    batch_size=BATCH_SIZE_TRAIN_MNIST,\n",
    "    shuffle=False,\n",
    ")\n",
    "\n",
    "mnist_test_out_loader = torch.utils.data.dataloader.DataLoader(\n",
    "    MNIST_test_out,\n",
    "    batch_size=BATCH_SIZE_TRAIN_MNIST,\n",
    "    shuffle=False,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def LPADirNN(num_classes=10, num_LL=256):\n",
    "    \n",
    "    features = torch.nn.Sequential(\n",
    "        torch.nn.Conv2d(1, 32, 5),\n",
    "        torch.nn.ReLU(),\n",
    "        torch.nn.MaxPool2d(2,2),\n",
    "        torch.nn.Conv2d(32, 64, 5),\n",
    "        torch.nn.ReLU(),\n",
    "        torch.nn.MaxPool2d(2,2),\n",
    "        torch.nn.Flatten(),\n",
    "        torch.nn.Linear(4 * 4 * 64, num_LL), #changed from 500\n",
    "        torch.nn.Linear(num_LL, num_classes)  #changed from 500\n",
    "    )\n",
    "    return(features)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist_model = LPADirNN(num_classes=3)\n",
    "loss_function = torch.nn.CrossEntropyLoss()\n",
    "\n",
    "mnist_train_optimizer = torch.optim.Adam(mnist_model.parameters(), lr=1e-3, weight_decay=5e-4)\n",
    "MNIST_PATH = \"models/mnist_3c_{}s_6iter_256.pth\".format(num_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Training routine\n",
    "\n",
    "def train(verbose=False):\n",
    "    for iter in range(MAX_ITER_MNIST):\n",
    "        for batch_idx, (x, y) in enumerate(mnist_train_loader):\n",
    "            max_len = int(np.ceil(len(mnist_train_loader.dataset)/BATCH_SIZE_TRAIN_MNIST))\n",
    "            output = mnist_model(x)\n",
    "\n",
    "            accuracy = get_accuracy(output, y)\n",
    "\n",
    "            loss = loss_function(output, y)\n",
    "            loss.backward()\n",
    "            mnist_train_optimizer.step()\n",
    "            mnist_train_optimizer.zero_grad()\n",
    "\n",
    "            if verbose:\n",
    "                print(\n",
    "                    \"Iteration {}; {}/{} \\t\".format(iter, batch_idx, max_len) +\n",
    "                    \"Minibatch Loss %.3f  \" % (loss) +\n",
    "                    \"Accuracy %.0f\" % (accuracy * 100) + \"%\"\n",
    "                )\n",
    "\n",
    "    print(\"saving model at: {}\".format(MNIST_PATH))\n",
    "    torch.save(mnist_model.state_dict(), MNIST_PATH)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "#train(verbose=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loading model from: weights/mnist_3c_alls_6iter_256.pth\n",
      "Batch 0/99 \tAccuracy 100%\n",
      "Batch 10/99 \tAccuracy 100%\n",
      "Batch 20/99 \tAccuracy 100%\n",
      "Batch 30/99 \tAccuracy 100%\n",
      "Batch 40/99 \tAccuracy 100%\n",
      "overall test accuracy on MNIST: 99.97 %\n"
     ]
    }
   ],
   "source": [
    "#predict in distribution\n",
    "MNIST_PATH = \"weights/mnist_3c_{}s_6iter_256.pth\".format(num_samples)\n",
    "\n",
    "mnist_model = LPADirNN(num_classes=3)\n",
    "print(\"loading model from: {}\".format(MNIST_PATH))\n",
    "mnist_model.load_state_dict(torch.load(MNIST_PATH))\n",
    "mnist_model.eval()\n",
    "\n",
    "acc = []\n",
    "\n",
    "for batch_idx, (x, y) in enumerate(mnist_test_loader):\n",
    "        max_len = int(np.ceil(len(mnist_test_loader.dataset)/BATCH_SIZE_TEST_MNIST))\n",
    "        output = mnist_model(x)\n",
    "        \n",
    "        accuracy = get_accuracy(output, y)\n",
    "        if batch_idx % 10 == 0:\n",
    "            print(\n",
    "                \"Batch {}/{} \\t\".format(batch_idx, max_len) + \n",
    "                \"Accuracy %.0f\" % (accuracy * 100) + \"%\"\n",
    "            )\n",
    "        acc.append(accuracy)\n",
    "    \n",
    "avg_acc = np.mean(acc)\n",
    "print('overall test accuracy on MNIST: {:.02f} %'.format(avg_acc * 100))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_in_dist_values(py_in, targets):\n",
    "    acc_in = np.mean(np.argmax(py_in, 1) == targets)\n",
    "    prob_correct = np.choose(targets, py_in.T).mean()\n",
    "    average_entropy = -np.sum(py_in*np.log(py_in+1e-8), axis=1).mean()\n",
    "    MMC = py_in.max(1).mean()\n",
    "    return(acc_in, prob_correct, average_entropy, MMC)\n",
    "    \n",
    "def get_out_dist_values(py_in, py_out, targets):\n",
    "    average_entropy = -np.sum(py_out*np.log(py_out+1e-8), axis=1).mean()\n",
    "    acc_out = np.mean(np.argmax(py_out, 1) == targets)\n",
    "    if max(targets) > len(py_in[0]):\n",
    "        targets = np.array(targets)\n",
    "        targets[targets >= len(py_in[0])] = 0\n",
    "    prob_correct = np.choose(targets, py_out.T).mean()\n",
    "    labels = np.zeros(len(py_in)+len(py_out), dtype='int32')\n",
    "    labels[:len(py_in)] = 1\n",
    "    examples = np.concatenate([py_in.max(1), py_out.max(1)])\n",
    "    auroc = roc_auc_score(labels, examples)\n",
    "    MMC = py_out.max(1).mean()\n",
    "    return(acc_out, prob_correct, average_entropy, MMC, auroc)\n",
    "\n",
    "def print_in_dist_values(acc_in, prob_correct, average_entropy, MMC, train='mnist', method='LLLA-KF'):\n",
    "    \n",
    "    print(f'[In, {method}, {train}] Accuracy: {acc_in:.3f}; average entropy: {average_entropy:.3f}; \\\n",
    "    MMC: {MMC:.3f}; Prob @ correct: {prob_correct:.3f}')\n",
    "\n",
    "\n",
    "def print_out_dist_values(acc_out, prob_correct, average_entropy, MMC, auroc, train='mnist', test='FMNIST', method='LLLA-KF'):\n",
    "   \n",
    "    print(f'[Out-{test}, {method}, {train}] Accuracy: {acc_out:.3f}; Average entropy: {average_entropy:.3f};\\\n",
    "    MMC: {MMC:.3f}; AUROC: {auroc:.3f}; Prob @ correct: {prob_correct:.3f}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MAP estimate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4 1 1 ... 1 2 3]\n"
     ]
    }
   ],
   "source": [
    "targets = MNIST_test_in.targets.numpy()\n",
    "targets_out = MNIST_test_out.targets.numpy()\n",
    "print(targets_out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist_test_in_MAP = predict_MAP(mnist_model, mnist_test_loader).numpy()\n",
    "mnist_test_out_MAP = predict_MAP(mnist_model, mnist_test_out_loader).numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc_in_MAP, prob_correct_in_MAP, ent_in_MAP, MMC_in_MAP = get_in_dist_values(mnist_test_in_MAP, targets)\n",
    "acc_out_MAP, prob_correct_out_MAP, ent_out_MAP, MMC_out_MAP, auroc_out_MAP = get_out_dist_values(mnist_test_in_MAP, mnist_test_out_MAP, targets_out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[In, MAP, mnist] Accuracy: 1.000; average entropy: 0.006;     MMC: 0.998; Prob @ correct: 0.998\n",
      "[Out-MAP, LLLA-KF, mnist_out] Accuracy: 0.098; Average entropy: 0.356;    MMC: 0.850; AUROC: 0.970; Prob @ correct: 0.291\n"
     ]
    }
   ],
   "source": [
    "print_in_dist_values(acc_in_MAP, prob_correct_in_MAP, ent_in_MAP, MMC_in_MAP, 'mnist', 'MAP')\n",
    "print_out_dist_values(acc_out_MAP, prob_correct_out_MAP, ent_out_MAP, MMC_out_MAP, auroc_out_MAP, 'mnist_out', 'MAP')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Laplace bridge"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "## play around with Backpack\n",
    "def get_Hessian_NN(model, train_loader, var0, device='cpu', verbose=True):\n",
    "    lossfunc = torch.nn.CrossEntropyLoss()\n",
    "\n",
    "    extend(lossfunc, debug=False)\n",
    "    extend(model, debug=False)\n",
    "\n",
    "    Hessian_diag = []\n",
    "    for param in mnist_model.parameters():\n",
    "        ps = param.size()\n",
    "        print(\"parameter size: \", ps)\n",
    "        Hessian_diag.append(torch.zeros(ps, device=device))\n",
    "        #print(param.numel())\n",
    "\n",
    "    tau = 1/var0\n",
    "    max_len = len(train_loader)\n",
    "\n",
    "    with backpack(DiagHessian()):\n",
    "\n",
    "        for batch_idx, (x, y) in enumerate(train_loader):\n",
    "\n",
    "            if device == 'cuda':\n",
    "                x, y = x.float().cuda(), y.long().cuda()\n",
    "\n",
    "            mnist_model.zero_grad()\n",
    "            lossfunc(model(x), y).backward()\n",
    "\n",
    "            with torch.no_grad():\n",
    "                # Hessian of weight\n",
    "                for idx, param in enumerate(model.parameters()):\n",
    "\n",
    "                    H_ = param.diag_h\n",
    "                    #add bias here\n",
    "                    H_ += tau * torch.ones(H_.size())\n",
    "\n",
    "                    rho = min(1-1/(batch_idx+1), 0.95)\n",
    "\n",
    "                    Hessian_diag[idx] = rho*Hessian_diag[idx] + (1-rho)*H_\n",
    "            \n",
    "            if verbose:\n",
    "                print(\"Batch: {}/{}\".format(batch_idx, max_len))\n",
    "\n",
    "    #combine all elements of the Hessian to one big vector\n",
    "    Hessian_diag = torch.cat([el.view(-1) for el in Hessian_diag])\n",
    "    print(\"Hessian_size: \", Hessian_diag.size())\n",
    "    num_params = np.sum([p.numel() for p in model.parameters()])\n",
    "    assert(num_params == Hessian_diag.size(-1))\n",
    "    return(Hessian_diag)\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "parameter size:  torch.Size([32, 1, 5, 5])\n",
      "parameter size:  torch.Size([32])\n",
      "parameter size:  torch.Size([64, 32, 5, 5])\n",
      "parameter size:  torch.Size([64])\n",
      "parameter size:  torch.Size([256, 1024])\n",
      "parameter size:  torch.Size([256])\n",
      "parameter size:  torch.Size([3, 256])\n",
      "parameter size:  torch.Size([3])\n",
      "Hessian_size:  torch.Size([315267])\n"
     ]
    }
   ],
   "source": [
    "Hessian_MNIST = get_Hessian_NN(model=mnist_model, train_loader=mnist_train_loader, var0=2,verbose=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "from scipy.special import digamma\n",
    "\n",
    "def log_beta_function(alpha):\n",
    "    return(np.sum([loggamma(a_i) for a_i in alpha]) - loggamma(np.sum(alpha)))\n",
    "\n",
    "def alphas_norm(alphas):\n",
    "    alphas = np.array(alphas)\n",
    "    return(alphas/alphas.sum(axis=1).reshape(-1,1))\n",
    "\n",
    "def alphas_variance(alphas):\n",
    "    alphas = np.array(alphas)\n",
    "    norm = alphas_norm(alphas)\n",
    "    nom = norm * (1 - norm)\n",
    "    den = alphas.sum(axis=1).reshape(-1,1) + 1\n",
    "    return(nom/den)\n",
    "\n",
    "def alpha_entropy(alpha):\n",
    "    K = len(alpha)\n",
    "    alpha = np.array(alpha)\n",
    "    B = log_beta_function(alpha)\n",
    "    #print(\"B: \", B)\n",
    "    alpha_0 = np.sum(alpha)\n",
    "    C = (alpha_0 - K)*digamma(alpha_0)\n",
    "    #print(\"C: \", C)\n",
    "    D = np.sum((alpha-1)*digamma(alpha))\n",
    "    #print(\"D: \", D)\n",
    "    entropy = B + C - D\n",
    "    \n",
    "    return(np.array(entropy))\n",
    "        \n",
    "\n",
    "def alphas_log_prob(alphas):\n",
    "    alphas = np.array(alphas)\n",
    "    dig_sum = digamma(alphas.sum(axis=1).reshape(-1,1))\n",
    "    log_prob = digamma(alphas) - dig_sum\n",
    "    return(log_prob)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "def compute_jacobians_with_backpack(model, x, y, lossfunc):\n",
    "    \"\"\"\n",
    "    Returns the jacobians of the network\n",
    "\n",
    "    The output is a list. Each element in the list is a tensor\n",
    "    corresponding to the model.parameters().\n",
    "\n",
    "    The tensor are of the form [N, *, C] where N is the batch dimension,\n",
    "    C is the number of classes (output size of the network)\n",
    "    and * is the shape of the model parameters\n",
    "    \"\"\"\n",
    "    #this is a bit hacky. Refactoring needed\n",
    "    if max(y) > 3:\n",
    "        y[y >= 3] = np.random.randint(0,3)\n",
    "    \n",
    "    loss = lossfunc(model(x), y)\n",
    "\n",
    "    with backpack(NetJac()):\n",
    "        loss.backward()\n",
    "\n",
    "    jacs = []\n",
    "    for p in model.parameters():\n",
    "        jacs.append(p.netjacs.data)\n",
    "    return jacs\n",
    "\n",
    "def transform2full_jac(backpack_jacobian):\n",
    "\n",
    "    jac_full = []\n",
    "    #batch_size\n",
    "    N = backpack_jacobian[0].size(0)\n",
    "    #num classes\n",
    "    k = backpack_jacobian[0].size(-1)\n",
    "    for j in backpack_jacobian:\n",
    "        jac_full.append(j.view(N, -1, k).permute(0,2,1))\n",
    "    jac_full = torch.cat(jac_full, dim=-1)\n",
    "    return(jac_full)\n",
    "\n",
    "def get_Jacobian(model, x, y, lossfunc):\n",
    "    return(transform2full_jac(compute_jacobians_with_backpack(model, x, y, lossfunc)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_alpha_from_Normal(mu, Sigma):\n",
    "    batch_size, K = mu.size(0), mu.size(-1)\n",
    "    Sigma_d = torch.diagonal(Sigma, dim1=1, dim2=2)\n",
    "    sum_exp = torch.sum(torch.exp(-1*torch.Tensor(mu)), dim=1).view(-1,1)\n",
    "    alpha = 1/Sigma_d * (1 - 2/K + torch.exp(mu)/K**2 * sum_exp)\n",
    "    \n",
    "    assert(alpha.size() == mu.size())\n",
    "    \n",
    "    return(alpha)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict_DIR_LPA(model, test_loader, Hessian, verbose=True):\n",
    "\n",
    "    lossfunc = torch.nn.CrossEntropyLoss()\n",
    "    extend(lossfunc, debug=False)\n",
    "    \n",
    "    alphas = []\n",
    "\n",
    "    max_len = len(test_loader)\n",
    "    for batch_idx, (x, y) in enumerate(test_loader):\n",
    "\n",
    "        J = get_Jacobian(model, x, y, lossfunc)\n",
    "        batch_size = J.size(0)\n",
    "        num_classes = J.size(1)\n",
    "        Cov_pred = torch.bmm(J * Hessian, J.permute(0, 2, 1))\n",
    "        #print(\"cov pred size: \", Cov_pred.size())\n",
    "        \n",
    "        mu_pred = model(x)\n",
    "        \n",
    "        #make sure that it fullfills all the properties:\n",
    "        #mu_pred -= mu_pred.mean()\n",
    "        #Cov_pred -= torch.matmul(Cov_pred.sum(dim=2).view(-1, 10, 1), Cov_pred.sum(dim=1).view(-1, 1, 10))/Cov_pred.sum(0)\n",
    "        \n",
    "        alpha = get_alpha_from_Normal(mu_pred, Cov_pred).detach()\n",
    "    \n",
    "        alphas.append(alpha)\n",
    "\n",
    "\n",
    "        if verbose:\n",
    "            print(\"Batch: {}/{}\".format(batch_idx, max_len))\n",
    "\n",
    "    return(torch.cat(alphas, dim = 0))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist_test_in_DIR_LPA = predict_DIR_LPA(mnist_model, mnist_test_loader, Hessian_MNIST, verbose=False).numpy()\n",
    "mnist_test_out_DIR_LPA = predict_DIR_LPA(mnist_model, mnist_test_out_loader, Hessian_MNIST, verbose=False).numpy()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "#McKay\n",
    "mnist_test_in_DIR_LPAn = mnist_test_in_DIR_LPA/mnist_test_in_DIR_LPA.sum(1).reshape(-1,1)\n",
    "mnist_test_out_DIR_LPAn = mnist_test_out_DIR_LPA/mnist_test_out_DIR_LPA.sum(1).reshape(-1,1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[In, DIR_LPA, mnist] Accuracy: 0.999; average entropy: 0.010;     MMC: 0.997; Prob @ correct: 0.997\n",
      "[Out-DIR_LPA, LLLA-KF, mnist_out] Accuracy: 0.107; Average entropy: 0.417;    MMC: 0.823; AUROC: 0.965; Prob @ correct: 0.284\n"
     ]
    }
   ],
   "source": [
    "acc_in_DIR_LPA, prob_correct_in_DIR_LPA, ent_in_DIR_LPA, MMC_in_DIR_LPA = get_in_dist_values(mnist_test_in_DIR_LPAn, targets)\n",
    "acc_out_DIR_LPA, prob_correct_out_DIR_LPA, ent_out_DIR_LPA, MMC_out_DIR_LPA, auroc_out_DIR_LPA = get_out_dist_values(mnist_test_in_DIR_LPAn, mnist_test_out_DIR_LPAn, targets_out)\n",
    "print_in_dist_values(acc_in_DIR_LPA, prob_correct_in_DIR_LPA, ent_in_DIR_LPA, MMC_in_DIR_LPA, 'mnist', 'DIR_LPA')\n",
    "print_out_dist_values(acc_out_DIR_LPA, prob_correct_out_DIR_LPA, ent_out_DIR_LPA, MMC_out_DIR_LPA, auroc_out_DIR_LPA, 'mnist_out', 'DIR_LPA')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Make some fancy 3D Dirichlet plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3.5528046e-07 1.7502197e-08 9.9999964e-01] [1.3341720e-05 9.9993658e-01 5.0059487e-05] [9.9999726e-01 1.1695286e-10 2.7654921e-06] [2.8933919e-06 9.9998975e-01 7.4475211e-06]\n",
      "[8.0104973e-03 1.5489871e-03 2.3099021e+04] [3.3982769e-03 4.5851826e+01 9.9649541e-03] [1.6646234e+06 1.2334236e-03 1.1260537e+01] [2.3885756e-03 1.7516371e+02 6.4065834e-03]\n",
      "2 1 0 1\n"
     ]
    }
   ],
   "source": [
    "MAP0 = mnist_test_in_MAP[0]\n",
    "MAP1 = mnist_test_in_MAP[1]\n",
    "MAP2 = mnist_test_in_MAP[2]\n",
    "MAP3 = mnist_test_in_MAP[3]\n",
    "\n",
    "d0 = mnist_test_in_DIR_LPA[0]\n",
    "d1 = mnist_test_in_DIR_LPA[1]\n",
    "d2 = mnist_test_in_DIR_LPA[2]\n",
    "d3 = mnist_test_in_DIR_LPA[3]\n",
    "\n",
    "t0 = targets[0]\n",
    "t1 = targets[1]\n",
    "t2 = targets[2]\n",
    "t3 = targets[3]\n",
    "print(MAP0, MAP1, MAP2, MAP3)\n",
    "print(d0, d1, d2, d3)\n",
    "print(t0, t1, t2, t3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dists = [Dirichlet(d0), Dirichlet(d1), Dirichlet(d2)]\n",
    "draw_triple_pdfs(dists, subdiv=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_map:  [array([9.9997365e-01, 7.7600584e-09, 2.6307867e-05], dtype=float32), array([1.3341720e-05, 9.9993658e-01, 5.0059487e-05], dtype=float32), array([3.5528046e-07, 1.7502197e-08, 9.9999964e-01], dtype=float32)]\n",
      "test_d:  [array([3.4447539e+04, 1.4655321e-03, 2.1521256e+00], dtype=float32), array([3.3982769e-03, 4.5851826e+01, 9.9649541e-03], dtype=float32), array([8.0104973e-03, 1.5489871e-03, 2.3099021e+04], dtype=float32)]\n",
      "test_targets:  [0, 1, 2]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "L = [4,1,0]\n",
    "test_map = [mnist_test_in_MAP[i] for i in L]\n",
    "test_d = [mnist_test_in_DIR_LPA[i] for i in L]\n",
    "test_dists = [Dirichlet(d) for d in test_d]\n",
    "test_targets = [targets[i] for i in L]\n",
    "print(\"test_map: \", test_map)\n",
    "print(\"test_d: \", test_d)\n",
    "print(\"test_targets: \", test_targets)\n",
    "\n",
    "draw_triple_pdfs(test_dists, subdiv=4, filename='MNIST3_in_dist_cool.pdf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "153\n",
      "153\n",
      "153\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "draw_pdf_contours(test_dists[0], filename='MNIST_3Classes_in_dist_coolwarm_0.png')\n",
    "draw_pdf_contours(test_dists[1], filename='MNIST_3Classes_in_dist_coolwarm_1.png')\n",
    "draw_pdf_contours(test_dists[2], filename='MNIST_3Classes_in_dist_coolwarm_2.png')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.06142883 0.00112431 0.93744683] [8.4837115e-01 8.3218107e-04 1.5079665e-01] [2.8097574e-04 1.3998334e-02 9.8572063e-01] [0.05177294 0.03389385 0.9143332 ]\n",
      "[0.02420382 0.00238482 0.5011989 ] [0.2642896  0.00284564 0.10667464] [1.1954285e-03 3.4163818e-02 1.4172046e+00] [0.00234906 0.00264598 0.02465811]\n",
      "4 1 1 6\n"
     ]
    }
   ],
   "source": [
    "MAP0_MNIST_out = mnist_test_out_MAP[0]\n",
    "MAP1_MNIST_out = mnist_test_out_MAP[1]\n",
    "MAP2_MNIST_out = mnist_test_out_MAP[2]\n",
    "MAP3_MNIST_out = mnist_test_out_MAP[3]\n",
    "\n",
    "d0_MNIST_out = mnist_test_out_DIR_LPA[0]\n",
    "d1_MNIST_out = mnist_test_out_DIR_LPA[1]\n",
    "d2_MNIST_out = mnist_test_out_DIR_LPA[2]\n",
    "d3_MNIST_out = mnist_test_out_DIR_LPA[3]\n",
    "\n",
    "t0_MNIST_out = targets_out[0]\n",
    "t1_MNIST_out = targets_out[1]\n",
    "t2_MNIST_out = targets_out[2]\n",
    "t3_MNIST_out = targets_out[3]\n",
    "print(MAP0_MNIST_out, MAP1_MNIST_out, MAP2_MNIST_out, MAP3_MNIST_out)\n",
    "print(d0_MNIST_out, d1_MNIST_out, d2_MNIST_out, d3_MNIST_out)\n",
    "print(t0_MNIST_out, t1_MNIST_out, t2_MNIST_out, t3_MNIST_out)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "dists = [Dirichlet(d0_MNIST_out), Dirichlet(d1_MNIST_out), Dirichlet(d2_MNIST_out)]\n",
    "#MAPs = [MAP0_MNIST_out, MAP1_MNIST_out, MAP2_MNIST_out]\n",
    "draw_triple_pdfs(dists, subdiv=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_map:  [array([9.6336575e-05, 6.1517805e-01, 3.8472557e-01], dtype=float32), array([0.06649538, 0.14541973, 0.788085  ], dtype=float32), array([0.9674727 , 0.01537188, 0.01715543], dtype=float32)]\n",
      "test_d:  [array([9.2783174e-04, 3.1196833e+00, 1.8261181e+00], dtype=float32), array([0.00193384, 0.00630239, 0.01469803], dtype=float32), array([0.07673869, 0.00336693, 0.00508528], dtype=float32)]\n",
      "test_targets:  [0, 1, 6]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "L = [27, 12,13]\n",
    "#12, 13, 3,5, 9,10, 27\n",
    "test_map_MNIST_out = [mnist_test_out_MAP[i] for i in L]\n",
    "test_d_MNIST_out = [mnist_test_out_DIR_LPA[i] for i in L]\n",
    "test_dists_MNIST_out = [Dirichlet(d) for d in test_d_MNIST_out]\n",
    "test_targets_MNIST_out = [targets_out[i] for i in L]\n",
    "print(\"test_map: \", test_map_MNIST_out)\n",
    "print(\"test_d: \", test_d_MNIST_out)\n",
    "print(\"test_targets: \", test_targets_MNIST_out)\n",
    "\n",
    "draw_triple_pdfs(test_dists_MNIST_out, subdiv=4, filename='MNIST3_out_dist_cool.pdf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "153\n",
      "153\n",
      "153\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "draw_pdf_contours(test_dists_MNIST_out[0], filename='MNIST_3Classes_out_dist_coolwarm_0.png')\n",
    "draw_pdf_contours(test_dists_MNIST_out[1], filename='MNIST_3Classes_out_dist_coolwarm_1.png')\n",
    "draw_pdf_contours(test_dists_MNIST_out[2], filename='MNIST_3Classes_out_dist_coolwarm_2.png')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# check out different values of the dirichlet for in and out of dist data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avg:  [2.2479300e+06 1.6509863e-03 1.0224555e+01]\n",
      "max:  2247929.2\n",
      "variance:  0.0004855976\n",
      "ent:  -651777.155090332\n",
      "avg:  [2.3190537e-03 2.3886182e+03 8.5335058e-01]\n",
      "max:  2388.6184\n",
      "variance:  0.0012322714\n",
      "ent:  -655977.8367102146\n",
      "avg:  [4.44689952e-02 1.13688540e+00 1.00080704e+09]\n",
      "max:  1000807230.0\n",
      "variance:  0.00028184248\n",
      "ent:  -882494.30078125\n"
     ]
    }
   ],
   "source": [
    "#in dist values\n",
    "average_alphas_in = []\n",
    "max_alphas_in = []\n",
    "var_alphas_in = []\n",
    "ent_alphas_in = []\n",
    "for i in range(len(np.unique(targets))):\n",
    "    #get all alphas beloning to that class\n",
    "    alphas = mnist_test_in_DIR_LPA[np.where(targets == i)]\n",
    "    #average alpha\n",
    "    avg_alpha = alphas.mean(0)\n",
    "    average_alphas_in.append(avg_alpha)\n",
    "    print(\"avg: \", avg_alpha)\n",
    "    #max alpha\n",
    "    max_alphas = alphas.max(1)\n",
    "    max_alphas_in.append(np.mean(max_alphas))\n",
    "    print(\"max: \", np.mean(max_alphas))\n",
    "    #variance\n",
    "    var_alphas = alphas_variance(alphas)\n",
    "    var_alphas_in.append(np.mean(var_alphas))\n",
    "    print(\"variance: \", np.mean(var_alphas))\n",
    "    #entropy\n",
    "    ent_alphas = alpha_entropy(alphas)\n",
    "    ent_alphas_in.append(np.mean(ent_alphas))\n",
    "    print(\"ent: \", np.mean(ent_alphas))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "avg:  [7.124416e-02 4.979935e+01 4.584105e+02]\n",
      "max:  499.00674\n",
      "variance:  0.040894285\n",
      "ent:  -1056142.7567662597\n",
      "avg:  [0.8459512  0.11533251 0.45956165]\n",
      "max:  1.38495\n",
      "variance:  0.11516662\n",
      "ent:  -692842.448373432\n",
      "avg:  [  2.716324 128.65588   98.72319 ]\n",
      "max:  228.7924\n",
      "variance:  0.066175975\n",
      "ent:  -839326.6815341115\n",
      "avg:  [209.13145     0.5829125   7.673742 ]\n",
      "max:  216.27553\n",
      "variance:  0.039767493\n",
      "ent:  -516369.0567560792\n",
      "avg:  [1.0818167e+02 1.3822620e+00 6.4399477e+04]\n",
      "max:  64507.418\n",
      "variance:  0.05828355\n",
      "ent:  -673634.6675872803\n",
      "avg:  [8.3159304e+00 1.4790748e-01 4.6989053e+02]\n",
      "max:  477.43695\n",
      "variance:  0.039114334\n",
      "ent:  -729917.3638184369\n",
      "avg:  [87.725586   1.5192872  5.447289 ]\n",
      "max:  92.74928\n",
      "variance:  0.080622084\n",
      "ent:  -590292.6172466278\n"
     ]
    }
   ],
   "source": [
    "#out dist values\n",
    "average_alphas_out = []\n",
    "max_alphas_out = []\n",
    "var_alphas_out = []\n",
    "ent_alphas_out = []\n",
    "for i in range(len(np.unique(targets_out))):\n",
    "    #get all alphas beloning to that class\n",
    "    alphas = mnist_test_out_DIR_LPA[np.where(targets_out == i)]\n",
    "    #average alpha\n",
    "    avg_alpha = alphas.mean(0)\n",
    "    average_alphas_out.append(avg_alpha)\n",
    "    print(\"avg: \", avg_alpha)\n",
    "    #max alpha\n",
    "    max_alphas = alphas.max(1)\n",
    "    max_alphas_out.append(np.mean(max_alphas))\n",
    "    print(\"max: \", np.mean(max_alphas))\n",
    "    #variance\n",
    "    var_alphas = alphas_variance(alphas)\n",
    "    var_alphas_out.append(np.mean(var_alphas))\n",
    "    print(\"variance: \", np.mean(var_alphas))\n",
    "    #entropy\n",
    "    ent_alphas = alpha_entropy(alphas)\n",
    "    ent_alphas_out.append(np.mean(ent_alphas))\n",
    "    print(\"ent: \", np.mean(ent_alphas))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# plot in and out of dist data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "in classes:  [0, 1, 2]\n",
      "out classes:  [3, 4, 5, 6, 7, 8, 9]\n",
      "max alphas combined:  [2.24792925e+06 2.38861841e+03 1.00080723e+09 4.99006744e+02\n",
      " 1.38495004e+00 2.28792404e+02 2.16275528e+02 6.45074180e+04\n",
      " 4.77436951e+02 9.27492828e+01]\n",
      "var alphas combined:  [0.0004856  0.00123227 0.00028184 0.04089428 0.11516662 0.06617597\n",
      " 0.03976749 0.05828355 0.03911433 0.08062208]\n",
      "ent alphas combined:  [ -651777.15509033  -655977.83671021  -882494.30078125 -1056142.75676626\n",
      "  -692842.44837343  -839326.68153411  -516369.05675608  -673634.66758728\n",
      "  -729917.36381844  -590292.61724663]\n"
     ]
    }
   ],
   "source": [
    "print(\"in classes: \", classes)\n",
    "print(\"out classes: \", classes_out)\n",
    "classes_in_map = dict()\n",
    "for i in range(len(classes)):\n",
    "    classes_in_map[i] = classes[i]\n",
    "classes_out_map = dict()\n",
    "for i in range(len(classes_out)):\n",
    "    classes_out_map[i] = classes_out[i]\n",
    "#print(classes_in_map)\n",
    "#print(classes_out_map)\n",
    "\n",
    "max_alphas_combined = np.zeros(10)\n",
    "for i, x in enumerate(max_alphas_in):\n",
    "    max_alphas_combined[classes_in_map[i]] = x\n",
    "for i, x in enumerate(max_alphas_out):\n",
    "    max_alphas_combined[classes_out_map[i]] = x\n",
    "var_alphas_combined = np.zeros(10)\n",
    "for i, x in enumerate(var_alphas_in):\n",
    "    var_alphas_combined[classes_in_map[i]] = x\n",
    "for i, x in enumerate(var_alphas_out):\n",
    "    var_alphas_combined[classes_out_map[i]] = x\n",
    "ent_alphas_combined = np.zeros(10)\n",
    "for i, x in enumerate(ent_alphas_in):\n",
    "    ent_alphas_combined[classes_in_map[i]] = x\n",
    "for i, x in enumerate(ent_alphas_out):\n",
    "    ent_alphas_combined[classes_out_map[i]] = x\n",
    "    \n",
    "print(\"max alphas combined: \", max_alphas_combined)\n",
    "print(\"var alphas combined: \", var_alphas_combined)\n",
    "print(\"ent alphas combined: \", ent_alphas_combined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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JSIiIiL1S9QCqyXB1O4Wbqd67EI1ZhEUiff4448n7H/yyScsW7Ys4dhXX32VsP/ZZ5+l3F6/fn3Gr/vxxx8n7L/zzjvlxdqaNWsYMWIEzz33HLFYjAsvvJCnn36agoKChGuS83z99dcT9seNG8fkyZMpKSnh888/Z8OGDeTn53PFFVeUx/Tu3ZvevXuX769cuZJ169Zx7733ZvxeRERERCT3ohZYoOJJatHkyZPp2LEjl156acJxd2fAgAF069aNFStW8Nprr3H22WcnxFxzzTW8/PLLTJw4kWeeeab8+KpVqzj33HPTvu78+fO5+uqrufHGGxOOv/TSS+y222507dqVww8/nM2bN3PjjTfy3nvvceedd1ZYD2vy5MkVFjW+++67Oe2008r3t23bxrhx42jbti29evXioIMO4vnnn+fAAw8sj4nFYsyfP58TTjiBgoICJkyYwLRp07j88svTvg8RERERqVsWZfiUmX0C/AHYAFR2oRGsOXWJu3eqcYZ1rF+/fr58+fKM41etWkWvXr2qDhRpIPSZFhEREQEze8Xd+1UV1yxiuxe7+18zTGBtxLZFREREREQatEhDBDMtrsLYGdHTERERERERabiqcw9Wlczsf82sQ220LSIiIiIiUl9FHSKImTUHTga6kHrGwGbAsUBHYERNExQREREREWkoIhVYZtYeeA7oU1UoQQEmIiIiIiLSZETtwboeOJhgBsGqpmv/pDoJiYiIiIiINFRRC6zh4fNmoBgoICi2iuNi2gNvApfUODsREREREZEGJOokF98CjnP3du7eBTgceAPo5u5dwmM/B15094VZzlVERERERKRei1pgvRlfOLn7f4D/AyabWdmQwReAc81scJZyFBERERGRJsAdliyBUaOgsBBiseD5lFNg6dLgfH0XtcBaa2Z7mdkwM/urmX0PuAYYAywxs18DMwjuz7oyy7mKiIiIiEgjtX07jB4NgwbB7NlQVBQUVEVFMGtWcHz06CCuPot6D9YjwH+AFuH+vu7e18zuBi4C+sbF9k2+WEREREREJJk7jBkDc+cGBVWy0lLYuhXmzAnipk8Hq2rKvToStQfrEWAxQQ+VARvC41cR3IsV/zb/U+PsRERERESk0Vu6FObNS11cxSsuDuKWLctNXtURqcBy91LgJGA8cB8wNjxeBBwN/Al4H1gI/DSbiYqIiIiISOM0aVJQPGWiuDiIr6+iDhHE3b8Bbk9x/EvCgktERERERCRTCxYEwwAzUVoaxNdXUYcIZszMJtdW2yIiIiIi0nhk2ntV3fhcqrQHy8yaAaeGu4+4+w4zOyWDNpsDBwNnoR4tERERERGpQn5+1fdfJcfXV+mGCD4C/CjcPhkYCfwVaACzz4uIiIiISEMxZEgwFXsmwwRjsSC+vko3RPC48NnitjNVTydNlIZo8+bN3HnnnZx44onsvvvudO3alW7dunHggQcyduxYnnzyybpOsdzMmTO54IILKCgowMzKH3l5eeTl5dGyZUu6du3KkUceyVVXXcXq1avTtnf11VfTtm1bTjrpJL7++uscvQsRERGR3Bo/PvNeqZYtg/j6Kl2BdT87C6Upccctg4fUgcaw8nWyadOmsffee3PRRRcBsHDhQv7v//6PDz/8kNtvv51nnnmGH/zgBxx66KG8/fbbtZLDF198wU9+8pOMYkeOHMndd9/NFVdckXD8jDPOYMeOHaxbt45bbrmF1atXM3HiRHr37s15551HcYqBxG+99RY33XQTmzZtYsGCBTz88MM1eh9jx45l7dq1NWpDREREpDYMGABDh1ZdZOXnw7Bh0L9/bvKqjkoLLHe/jOBeqkPcfUJ4uAQ4EmgD5FfyaA0ci4YS5lRjWfk63tVXX80ZZ5zB+vXrGTBgAAsWLGC//fYDwMw48cQTWbhwIQUFBSxdupT+/fvz0ksvZTWH0tJSzjrrLD7++ONI13Xr1q3CMTOjU6dOnH766Sxbtoz27dtTWlrKfffdx/HHH09RlIHHEc2cOZMpU6ZUHSgiIiJSB8xg6lQYPnxnR0G8WAwKCoLzU6fW30WGoYpZBN39DXf/d9yhi919sbtvcfdtlTy2uvtzwEW1m7qUSV75OnnsavLK1w2hJ+v+++/npptuKt+/4447aNas4i2De++9N+effz4AGzduZPjw4bz//vtZycHdueCCC5g7d27ka/Py8tKe7969O5PiFnB48cUXmTBhQkLMfvvtx5VXXknr1q0ZMmQIZ5xxRuQ8ABYtWsSYMWOqda2IiIhIrjRvDtOnw8KFMGJE4oiskSNh0SKYMSOIq8+iTtO+2MyuMrM+VQW6+z3VzEkiakwrXwOsX7+eyy67rHy/Z8+eHHbYYZXGxxcP69ev5/LLL69xDkVFRZx22mn88Y9/rHFblTnttNNo3759+f59991XYZjjxIkT2bRpE/Pnz6dly5aRX2PGjBkMHjw45RBEERERkfrGLBgu+OijsGULlJQEz488Ur+HBcaLWmDNB34D1J9ZBaRRrXwNQe/Vpk2byvcHDhyYNv7AAw+koKCgfP+xxx7jgw8+AOCPf/wjbdu2LZ9sokePHgC8++67HHPMMQkTUTz00EMAFBcXM2LEiISeq5dffpkePXrQo0cP7rjjjqy8z1122YUjjzyyfL+0tJQHH3wQgClTptC8efOU+ZW599576dmzJx07diQvL6887o033gDgrrvu4tJLL2Xbtm3l1wwcOJAePXpU+TcVERERkeqJWmA1J5jEYn0t5CLV1JhWvgZYkJRgz54908bHYjF233338n13L59Z8Oc//zlnnnlmhWv23ntvZs6cmbK9/Px8nnjiCUaOHFl+7Hvf+x5r165l7dq1XHzxxZm+lSodeOCBCfvPPvssAOeccw4vvvhipddNmzaN888/n169evHJJ5/w0UcfMXjw4ISYCy+8kBkzZiQcW7x4MWvXrmXx4sVZegciIiIiEi9qgfVngskrzqmFXKSaGtPK10CFYXK77rprldfED7UDeOedd8q327Vrl/KaTNqtbV27dk3Yj3/v3/nOdyq97ne/+x0AJSUlxGIxOnfuzKxZs9h7771rJ1ERERERyUjUAus64DmC2QXTMrPsTucmlYq6knV9XvkaYMOGDQn7LVq0qPKaXXbZpdI2rJJpZio7nkv5Sf8xNm/eXL7dPM0dnO+99x4ATzzxBMOGDeOLL76goKCA6667rnYSFREREZGMVJyWLb1hBL1Y15rZz4BngfeBLUlx3wUOrXl6konGtPI1QNu2bfniiy/K9zOZoGHHjh0J+5X1WtU38fdHQeZ5H3zwwfzrX/8CYP78+fTp04eHHnpIswWKiIiI1LGoPVh/BR4C9gYOA64GJgMzkh6XVXK91ILGtPI1QO/evRP2v/rqqyqv+fLLLxP2DzrooKzmVFs2btyYsL/XXntldN3NN9+cMBX8xx9/zODBg/ntb3+b1fxEREREJJqoBVam6n7sVRPSmFa+BjjxxBMT9levXp02vqSkhHXr1pXvN2vWjOOPP75Wcsu2t956K2H/2GOPzei6o446ir/97W+0adOm/Ji7c+WVV/LYY49lNUcRqV/cYckSGDUqcY2YU04Jlu1oCGsdiog0ZtUpsCyDh+RQY1r5GmDs2LEJ066XDYWrzGuvvZYwjPDUU0+lS5cu5fux5D9IhnJxj9bLL79cvh2LxTjrrLMyvnbo0KGsXLmSww8/POH4PffsXIKuPtxnJiLZs307jB4NgwbB7NnB+ofuwfOsWcHx0aODOBERqRtRv3k+B3QB8tM82gJHAyVZy1Kq1FhWvgbo2LEjN998c/n+mjVrWLJkSaXxDzzwQPn2rrvuyq233ppwPn4iCY/w0278ELza8Oqrryb0zo0dO5Z99903o2svueQSIBhS+PzzzydMHf/555+Xb9f2exCR3HGHMWNg7tygoEq+77a0FLZuhTlzgjj1ZImI1I2oBdY4d//U3beleWx2938CJ1bZmmRVY1j5usyFF17IhRdeWL4/YcIESkoq1uyrVq1iypQpALRp04bHH3+czp07J8Tsscce5dsbN24sL7KSF+5N1rZt2/Lt+NeOXwS5MsmFXPJ+aWkpEyZMKN8fOHAgt912W0JM8sQd2+N+kl6xYgVTp04FgiGRt99+O/vvvz8Affv2Tfke4t9H8r1fIlL/LV0K8+YFxVU6xcVB3LJluclLREQSRSqw3H1NJnFmtp+7P1e9lESCoW133nknt99+O23atGHx4sWceuqpfPDBB+Ux//jHPzjuuOPYtm0b/fr14/nnn+fQQytOXvnDH/6Qjh07AkFhMW7cOMaPH8/kyZMT4pInyhg1alT58MK3336brVu38sADD/Dmm29Wmf/HH3+csP/OO+9QGv7cvGbNGkaMGMFzzz1HLBbjwgsv5Omnn04YFgmwLOnb0euvv56wP27cOCZPnkxJSQmff/45GzZsID8/nyuuuKI8pnfv3gmThqxcuZJ169Zx7733VvkeRKR+mTQp83UMi4uDeBERqQPunvUHMBs4oTbazvWjb9++HsV///vfSPFStU8//dRvu+02P/bYY7179+7evXt379Kli++3335++umn++zZs72kpCRtGytWrPDDDjvMW7Ro4T169PCrr77ai4qKnGDhbAe8a9eu/thjjyVc99e//tV79uzp+fn5fswxx/gzzzyT9nXmzZvnV111lefn5ye0DXi7du28S5cu3qlTJz/22GP9xhtv9Pfffz9lO/fff7/HYrEKbYwePdrd3Y866qjyY4WFhb7bbrv5oEGDfOnSpRXaeu+99/yEE07wgoIC79Gjh990002+Y8eOtO8jnj7TIvVDQYF7MPAvs0dhYV1nLCLSuADLPYP6wTziIG0zOxK4guBerF2oOKlFM4Jp3Fe5e59q1Hz1Sr9+/Xz58uUZx69atYpevXrVYkYiuaXPtEj9EItFu68qFguGiouISHaY2Svu3q+quEgLDZvZ4cBTBIUV7Cyu4v+XX3Zs7yhti4iISOXy86u+/yo5XkREci/qJBfXAS2oOB17qinaX6hZaiIiIlJmyJCKy3BUJhYL4kVEJPci9WABfYE3gIVAMXAA0BlYFBczmKC4+lUW8hMRERFg/Hh4/PFgKvaqtGwZxIuISO5FLbAAvu/uGwHMrDWwErjP3deGx2YDDwFa5lBERCRLBgyAoUODda7SzSaYnw/DhjW85TlERBqLqEME344rrlq6+2ZgCrDIzL4dxnQAegGXZS9NERGRps0Mpk6F4cN3LiYfLxaDgoLg/NSpQbxITbnDkiUwatTOz11hIZxySrA2mxa0FqkoaoG10sx+FfZSbTWz64E7CHrClpvZ+8CcMPZn2UtTREREmjeH6dNh4UIYMSLxC+/IkbBoEcyYEcSJ1NT27TB6NAwaBLNnB5OsuAfPs2YFx0ePDuJEZKeoQwTvJhgSGCOY0OJUd7/ezP4fMBPYnZ0TXeyWtSxFREQECHqmBgyARx+t60ykMXOHMWNg7tzUs1eWlgb3A86ZE8RNn65eU5EykXqw3P0/wM+Bb8JDC8Ljs4GbSZxF8K/ZSFBEREREcmvpUpg3r+qlAYqLg7hly3KTl0hDEHWIIO4+BegBHObuE+KOXwUMBK4HxgC/yE6KDU/UxZtF6it9lkVEmqZJk9JPphKvuDiIF5FApUMEzWxPd1+X6py7fwp8muL4S8BL2Uuv4cnLy6OkpIRmzaozQaNI/VJSUkJeXl5dpyEiIjm2YEEwDDATpaVBvIgE0vVgrTGz7jnLpJEoKChgy5YtdZ2GSFZs2bKFgoKCuk5DRERyLNPeq+rGizRm6QqsPGCWmXXLVTKNQZs2bfjyyy8pKSmp61REaqSkpIQvv/ySNm3a1HUqIiKSY/n5tRsv0phVdQ/Wd4E3zewWM+uci4QautatW1NYWMj777/PV199xY4dO3QfizQY7s6OHTv46quveP/99yksLKR169Z1nZaIiOTYkCEV11qrTCwWxItIoKobhS4BXgCGAS+b2dPA79397VrPrIEyMzp16sTmzZvZtGkTn332mXqzpEHJy8ujoKCADh060Lp1a0zz7oqINDnjx8PjjwdTsVelZcsgXkQC6Qqsje7+h3D7VTObCJwB/M3M3gJucfeXaz3DBsjMaNOmjYZWiYiISIM0YAAMHRqsc5Xu/qr8fBg2DPr3z11uIvVdus7f4fE77v6Nu//J3Q8CHgRuNrPnzeykbCZkZn3NbJGZLTazf5pZ3yriW5nZvWa23MxeNbOLUsR0MLMdZuZJj4uzmbuIiIhIY2AGU6fC8OFQWFhxuGAsBgUFwfmpU7XIsEi8SguZiZwlAAAeHUlEQVQsd/9nmnPz3P0YYDxwupm9ZmY/NbMazU1uZvsBzwLL3H0g8C6w0Mx6pbnsUYJi8HDgUuAOM/tVUsxQgkk74n0NTK1JviIiIiKNVfPmMH06LFwII0bsLLQKC2HkSFi0CGbMCOJEZKfICw3Hc/flwE3AJ8ADwHtmNt7MWlWzyWuBtsCScH8p0IZg8eIKzOw44AfACnf/JowHuMrMdosLHQz0AXrFP9z9y2rmKSIiItLomQXDBR99FLZsgZKS4PmRRzQsUKQy1S6wzOwkM/sHsBI4DjCgG3AL8IGZ/TZie3nsHJZYdktlUfj8w0p6x0bEx7t7WXwBcHzYbgHQzt3fcPfVcY+1UfITERERERGpSqUFlpn9IsWxAjO7wMzeBOYAxxAUVgBlc5Eb8BrwUsRc+gBlPV/bk861Ag5Jcc1hlcQDHBE+nwgcb2ZfmdmKcMr5PSLmJiIiIiIiUqV0PVg3lG2Y2Z5m9nvgQ+APwL4kFlYG7ACmAX3d/Wh3nxsxl93jtlPNa94lzTXp4n8U5tcW+DZwGfAfMxsWMT8REREREZG00k1K0d7M7iYoYn5IMElEqt6qL4D/Be5x909qkEvbuO1UK/O2TXMsXfy+wCaCe7nKtAYeMbMD3f295AvNbBwwDmDPPfesIm0REREREZFAVfdg/ZxgBr5mBMVUfGG1GjgX2MPdr6lhcQWQZpUFADZHvGYzgLsf7u5tgXbA2cC/w/MtgdNTXeju97t7P3fv17FjxyrSEhERERERCWQ6yUV8YfUUMNjde7v7ZHf/Oku5rIvbTrWawodprqky3t03uvsDQF/gkfBwt6hJioiIiIiIVCaTAsuAbcBkoLe7/8Ddn66FXP5NsDYVQIukc8Xs7HmKVzYte3I87JzqPYG7bwfOJ7hnbE30NEVERERERFKrqsDaSrDO1Z7ufq67r6qtRNx9G/D3cLd9+Fy2dN18IGZmz5nZp2Z2eHj8kfh4MyuL/xp4Mjy2d7iAcfxrfUGwdtf0rL8RERERERFpsqoqsAaG91etz0k2wULDm4Gypev6AFuAa8Lto4FOwGgAd38KeAI4xMx2CWMAbgiLKICXgTfN7MGyxYfN7HjgWnf/qNbfkYiIiIiINBnpCqwL3P31nGUCuPvbBAsEH25m/yK4X2qQu79JMERwEfAZMCPuslMIiqxXgD8Bl7n7xLjzlwP/Bf4HWGpm1wAb3f3BWn47IiIiIiLSxJh7qhnOpUy/fv18+fLldZ2GiNRT7rB0Kdx6Kzz+OBQXQ34+DBkCEyZA//5gqabhERERkQbFzF5x935VxWU6i6CIiCTZvh1Gj4ZBg2D2bCgqCgquoiKYNSs4Pnp0ECcidcsdliyBUaOgsBBiseD5lFOCH0n0e7OIZIsKLBGRanCHMWNg7tygoCotTTxfWgpbt8KcOUGcvryJ1B39GCJ1QUV906UCS0SkGpYuhXnzgi9o6RQXB3HLluUmLxFJpB9DpC6oqG/aVGCJiFTDpElB8ZSJ4uIgXkRyTz+GSK6pqBcVWCIi1bBgQcV/NCtTWhrEi0ju6ccQyTUV9VJrBZaZHVRbbYuI1LVMv7BVN15EskM/hkiuqaiXZtW9MFy0N5+KRZoBHYC7gcOqn5qISP2Vn1/1r5PJ8SKSe/oxRHJNRb1EKrDMrCVwB3A6QXElItIkDRkS3KicyT+isVgQLyK5px9DJNdU1EvUIYL3AGOBAoKeqnQPEZFGa/z4zL+ItWwZxItI7g0ZEvzIkQn9GCLZELVIV1Hf+EQtsE5GxZOICAMGwNChVf/DmJ8Pw4ZB//65yUtEEunHEMk1FfVSnUku/gucChwLHJPicSwwGliXpRxFROodM5g6FYYP37mAZLxYDAoKgvNTpwbxIpJ7+jFEck1FvUSd5OIfwGJ3f6yqQDN7t3opiYg0DM2bw/TpwRS7t94Kjz8ejKXPzw9+kZwwQV/WROpa2Y8hY8YEU2IXFyfeOxmLBV9yhw3TjyGSHWVF/Zw56e+vUlHfeJlHWN3MzA4ApgLHufumKmIvd/dbaphfnevXr58vX768rtMQERGRGnDXjyGSO9u3Z17UN29ed3lKNGb2irv3qzIuYoH1AHA40AJ4rpKwGNAJGOTuLTNuvJ5SgSUiIiIiUamob3xqq8AqBZxgoot0Fxrg7p6XceP1lAosERERERHJtMCq9kLDaDZBERERERGRBFELLAfeADZQeQ+WAe2APjXIS0REREREpMGJWmD9yd3HZRIY3q8lIiIiIiLSZERaByvT4iqMPSt6OiIiIiIiIg1XdRYarpKZ/bQ22hUREREREanPqjXJhZk1A3YDdqHiZBfNgNPMrIu7/7aG+YmIiIiIiDQYkQssM7se+CVBcZVOH0AFloiIiIiINBmRCiwzOxu4lp1rYaXT4BcZFhERERERiSLqPVgXhM+ZrIF1b8S2RUREREREGrSoQwR7ApOBvwHFQD/gBGBiXMzPgP+6+y1ZyVBERERERKSBiFpgfebu58btP29mZwJt3X0ugJl9CLxqZjPc/YMs5SkiIiIiIlLvRR0iuM7MdjGztmb2IzMrAK4HHjOzy82sF3AW0Br4dZZzFRERERERqdei9mAtBOYBvYEuwFx3P9nMlgE3h48yw7KTooiIiIiISMMQtQfrXuAQoCvBRBc9w+PjCO7JKuPAthpnJyIiIiIi0oBEKrDc/QvgRGAZsBG4ITz+X2AEsJ6g8CoBrspqpiIiIiIiIvVc5IWG3f014NAUx58ysz0JerjWufsnWchPRERERESkwYhcYKXj7tuApdlsU0REREREpKGIeg8WZtbazCaa2X/CKdnjz00ys3Oyl56IiIiIiEjDEanAMrN2wMvAL4FeQEH8eXcfD+xjZn8xM8taliIiIiIiIg1A1B6s3xAUVumKp2uBHwHnpokRERERERFpdKIWWCOAa4A9gJYEMwmmUgqcV4O8REREREREGpyok1yYu99UvmPmKWKuAQqBfWuSmIiIiIiISEMTtQfrMzP7f2aWcJ2ZNTezo8xsDjvXv6qsd0tERERERKRRitqDNQW4E7jOzNYAXc3sI6BDXFsGOPB01rIUERERERFpAKL2YN0LPAG0B/oCzYEu4XP8xBdfEgwVFBERERERaTIiFVjuXkowQ+Dvga+pOJugAS8CR7j7B1nJUEREREREpIGIOkQQd98O/NLMbgaOBvYBWgCfAi+5+6qsZigiIiIiItJAVFpgmVlbd690ogp3/wr4e3WvFxERERERaWzSDRF8vYZt1/R6ERERERGRBiVdgdXVzPaqTqNm1oNg8gsREREREZEmI909WHnACjN7A/gmQpvNgV7h9SIiIiIiIk1GVZNctAYOq0a7ZWthiYiIiIiINBlR18ESERERERGRSmQyTXvyWlciIiIiIiKSQroC6z2gB/AUMAVYn2GbLYAfAhfWKDMREREREZEGptICy933MbPjgXOBBwnWvLrH3ZdU1aiZPQOMyVqWIiIiIiIiDUDae7Dc/Rl3HwnsC6wCZpjZcjM7y8xaprnOgduzm6qIiIiIiEj9ltEkF+7+qbvfDOwDXA0MAdaa2SQz26eSa27IXpoiIiIiIiL1X6RZBD3wpLuPAL4DfAk8ZWZPmtlJZqYJMUREREREpMmq9jTt7v4xMAd4Fjgu3H7XzH5pZh2ylJ9IdO6wZAmMGgWFhRCLBc+nnAJLlwbnRURERERqQeQCy8yamdn/mNk/gdeAc8J2DNgTmAh8YGaTs5ppU6RCIbrt22H0aBg0CGbPhqKi4O9UVASzZgXHR48O4iSRPm8iIiIiNWae4ZcmM9sdOA84G+hUdjh89rjtj4A/Ave7e6ZTu8e/Tl9gEsEMh6XAJe7+Spr4VsAtwACCQu/P7v6HqDGV6devny9fvjzq26i57dthzBiYOxe+/hpKS3eei8UgPx+GDoWpU6F589znVx+5B8XT3LlBQVWZ/HwYPhymTweNag3o8yYiIiKSlpm94u79qoqrsgfLzE4ws78TrIt1JfAtEgsrwv0XgFOAHu4+sZrF1X4EQw6XuftA4F1goZn1SnPZo8Bw4HDgUuAOM/tVNWLqD/edX3aLihK/7EKwv3UrzJkTxKlnIbB0Kcybl764AiguDuKWLctNXvWdPm8iIiIiWVNpgWVml5rZW8ATwFAgj6CQcnb2WH0N/An4trsf5e4z3b2kBvlcC7QFytbaWgq0Aa6vJMfjgB8AK9z9mzAe4Coz2y3TmHpHhUL1TJoU/E0yUVwcxIs+byIiIiJZlK4H61aCadlT9VatA34J7O7uY9399eSLzWyvKImYWR5BLxPA1vC57BvfD80s1aLII+Lj3b0svgA4PkJM/aJCoXoWLKjY+1KZ0tIgXvR5ExEREcmiTCa5KOutMmAhcDKwj7v/3t03pLmu0vumKtEHaBVuJ89A0Ao4JMU1h1USD3BEhJj6RYVC9WRaJFQ3vrHS501EREQka1L1CiXbCjwM3O3uqzJp1MxOJhjqF8Xucduphhl2SXNNuvhMYhKY2ThgHMCee+6ZKqR2qVConvz8qoe5JceLPm8iIiIiWZRJgbUGOBC4J8N1hFsRLEIcVXxBluou+lQFW9mxdPGZxCRw9/uB+yGYRTBVTK1SoVA9Q4YEU7Fn0hsTiwXxos+biIiISBZVVWDdCTwOfBOhzXxgAnBMxFyq+ll8cyXXtK4iPpOY+kWFQvWMHw+PPx7MeFeVli2DeNHnTURERCSL0hVYG939kuo0amZLgM8jXrYuvokU5z+s5JreVcRnElO/qFCongEDgrWa5sxJP4wtPx+GDYP+/XOXW32mz5uIiIhI1qSb5OK26jYaTn5xY8TL/k0w7TtAi6RzxeH5ZGVTrifHQ+JU71XF1C9lhUJVQ7FUKCQyCxbCHT4cCguD3pZ4sRgUFATnp07VIsNl9HkTERERyZpKCyx3v6EmDbv79RHjtwF/D3fbh8/Nw+f5QMzMnjOzT83s8PD4I/HxZlYW/zXwZISY+kWFQvU1bw7Tp8PChTBixM6/X2EhjBwJixbBjBlBnAT0eRMRERHJmkymac+lawnuiyr7ibwPsAW4Jtw+GugEjAZw96cIFkI+xMx2CWMAbnD3LzKNqZdUKFSfWdAr8+ijsGULlJQEz488ot6XyujzJiIiIpIV5p77SfLSMbNDgT8QzPpXClzs7svMrAVBj9OBwI/d/cUwvhVwF9AP2AH8xd1vTWqzypjK9OvXz5cvX56V9yYiIiIiIg2Tmb3i7v2qjKtvBVZ9Y2afA+/XdR6hDsD6uk5Cmgx93iTX9JmTXNLnTXJNn7mGr7u7d6wqSAVWA2JmyzOpmkWyQZ83yTV95iSX9HmTXNNnrumob/dgiYiIiIiINFgqsERERERERLJEBVbDcn9dJyBNij5vkmv6zEku6fMmuabPXBOhe7BERERERESyRD1YIiIiIiIiWaICS0REREREJEtUYDUAZtbKzG43s9fNbImZ/cHMWtd1XtI4mdl3zexJM9tgZp+a2T1m1qau85KmwcxuNDONXZecMLMDzWySmc03s+vNbK+6zkkaFzM70syeNrM1ZvZy+F3uQjNrVte5Se3RPVj1nJnlAU8CxwB7AMXAx8AS4Dh331GH6UkjY2b9geeB/KRTLwMD3b0k91lJU2FmRwLPATF3t7rORxovM2sO3AKcD/wGuNXdv67brKSxMbMfAPOAT4A+7r7BzCYD5wD3u/u5dZqg1Br1YNV/pwLHAe+6+8fu/hWwGjgKOK1OM5PGaCLwc6A/cHPc8e8BP6yTjKRJMLN2wDT075LUMjMrABYCFwM/dfcbVVxJLfk9kAe85O4bwmMPhs9nazRS46XuyfrvzPB5U9yxjeHz6cCfc5qNNFpm1hn4jbu/EB5abmY9gVHhfs+6yUyaiPsBDamQXLgHGAjMdPcZdZ2MNGr7hs/fNbOYu5cCX4bH8tAPSo2W/sPWY+HwwMPC3W9ShBxhZrvkMCVpxNz9k7jiqszzcdvv5jIfaTrM7GyCLx3P1XUu0riFQ7bODHf/UIepSNPwVvi8D3B9uL1H+Dzf3TdWuEIaBRVY9dueQKtwO9W9VvnA7rlLR5qgduHzBuCpukxEGicz2w84F7ikrnORJuHi8LkUOMvMXjOz5WZ2iZnpvj/Jtpvitq8xs7uAswjuy9JtHo2YhgjWb7vFbZdWEtMB9SxI7Tk0fNY9CpJ14UQDDwBj3b1Y32+lNplZPjAo3H0FGAscBCwFbgN2Ba6pm+ykMXL3v4b3l95NMCTwAqAEONPdN6W9WBo09WDVb83rOgFpusJ7sgYDTwN31HE60jjdBDzm7q/VdSLSJOzHzh+Wi9y9JPzsPREeu8zMOtVNatKIvQ68CjwU7ucBD5vZGXWWkdQ6FVj124aqQ8pvlhTJthuBNcBPwhtzRbLGzI4mWH7iaTM7wMwOANrGnT8gnO1NJFsK47bjv/+sCJ9bAAfnLh1p7MzsZ8ALwLPu/jPgurjT95pZ29RXSkOnAqt+WwNsC7fzUpwvBt7PXTrSVJjZCcAJwInu/mV4rDCceEUkG44G+gH/BVaFjx/FnV8FDMh9WtKIrY/bjp8e+9O47V1zlIs0cmbWBriT4Lv2SgB3/w07J49qRTCbpTRCKrDqMXffDvwr3G2ZImRpGCOSNeEQmZuAQe6+LjyWB9wF6CYZEWmo1rCzyNoj7nj8LL3v5S4daeQOYOdEZfGjjf4Ut61e+kZKBVb9V7YgXYe4Yy3C54dznIs0cmYWI1jstTsw38xWm9mbBL/wfsfdU81mKRKZu1/v7hb/IG5dv/DYorrLUBobdy9h57+bu5nZXuF22dDBd4HlOU9MGqv/i9vuErf9Vfi8HXgpd+lILqnAqv/+AjwL7Glm3cJ7Eg4A/snOGyZFsuXXwPFAR2D/8LEfwYyWr9dhXiIi2fBr4M1w++zw+WiCL7s/d3ctdi1Z4e4fApPD3bPNrFm4FMDp4bHr3P2juslOapumaa/n3L3EzIYBtxIswrmRoIfhyvDXOJGsCO+7uipNiAosEWnQ3H2jmQ0EbgDONLNjgSLgGHd/sW6zk0boPIJe0XMJJlMpAbYAo9x9Zl0mJrXL9GONiIiIiIhIdmiIoIiIiIiISJaowBIREREREckSFVgiIiIiIiJZogJLREREREQkS1RgiYiIiIiIZIkKLBERERERkSxRgSUiIiIiIpIlKrBERERERESyRAWWiEgTZ2bXmtlXZuYpHhOquNbMbE2K63aY2QdmdoSZbUpx/ksz2ztFe1ebWWlS7Lrw3Coz+6aSPDeb2Z+T2trDzO41s7Vm9rGZvWlmj5vZyWaWZ2a/M7NWcfHxf4Ovzez9FH+Xr8L2vow/Vs2/e38zu9vM/m1mW8xsvZm9YmYLzGyCmR1sZt8ys2lh/I9TvP8zq/PaIiJSe1RgiYg0ce7+G2BX4A8pTp9nZpbm8uOBvZKObQYOcPc93P1FoD3w+6SY9sAsM8tPyuXG8NxcwIEfAd3Dc72AbsB7SW09DrR395+WHTCzAcBrwDHAMHfvAvQC/gjcAWwALk/xfj4ABgH57t49jI13h7v3cPddgSOAdSnaSMvM2pvZTGApcD7wCtDP3Tu4e1/gAqBnmP8nwEHh+58NHBb19UREJLdUYImICO5eSlCovAZsjTu1D3BimkvPBZ5JOvaGu78T13aJu18OrEyK+zZwX4pcNgK3AP919znu7nHnPgeWJF0y1913lO2ERdtMgkLtfHd/vew9uvs84HvAlyneSykw2t2fi3/Nyrj7S8AogkIwI2Z2EMHfeER46Dx3P9PdV8e1+567nweclaKJ1zJ9LRERqRsqsEREpMw3wFfAw0nHf5Eq2Mw6ExRfU1K0k8pGgh6ZeGeY2fkpYj8BvqiknW1V7A8B9gi3tyadw90/Bs5I0e4Kd19cyWum5O5LCXqiqmRm7YE5cblNd/cKBWZc2w8Cf0o6tqOScBERqSdUYImISLK7k/aHmNmeKeLOAv4OfB6h7dOoWDjdbmbJQ99KiNAzlKRnUtttkwPc/QXgX0mHr63m612XYdwUIP6+sxszuOY3gIoqEZEGRAWWiIgkcPf/AAvjDsWA8+JjzCwGjAXuidj8uwTD47bHHWsOzAx7xLIhvuA7DFhhZiNT3Ev2RPxOeL9YZO7+clUxZvZt4Mdxh95z91UZtL2OikMi071OzMxGmdnfzWylmRWb2bpwso+OKeJ7hLEbkib0mJkUd4yZLQkn9yiOi7sg09xERJoKFVgiIpLKXUn7Z5vZLnH7JwAb3D25F6hK7v48FYcddgUeNbNmUdtLYT7wddz+XsBjwEozOzkujxvcfUsWXi8To5P2MxpWCODuqYZQVhD+7eYCM4Ar3P3bBP+d9gB+DrxgZgVx8c0J7rsbDpzo7u2AnwDFSe32DON2J7gnrx3wu0zzFxFpalRgiYhIKvOA9+P2OwEj4/bHAfdWt3F3n0LFGfq+D9xa3Tbj2v4UuCjFqYOB2WFPTL+avk5EyUMgP62F1xhLcP9ZHsEEImVDIT8Lz+8PnBIXP4xgZkUIvw+4+1+BS5PavQhoCVgYs83drwAeyf5bEBFp+FRgiYhIBe5eQsUC6hcAZtYFGAhMr+HLTACeTDp2kZn9pIbt4u73Az8jxSQXwADgX2Z2YU1fJ4JvJe1vroXX2D9uO77HLL5Hqkvcdvz0+k+ZWVkBfT/wdoq4LgR/tz7h/q/Q/WEiIhWowBIRkcpMIfHL+RFmdjBwNvAXdy+qSeNhEfc/QPK9SFOAPhWviNz+Q8ABwJ8JJs2I1wy408yG1vR1MpQ8s2KFiTey4DbgH8C/w23M7ACgdVxM/DDP1+O22wCPmdmDQKG7X1lJ3P7AMjO7lOA+sv/NYv4iIo2CCiwREUnJ3b+kYi/VBQSzB1Z7eGDSa2wEhpK4LlUB8GCW2v/Q3c8kKLQepmKhdVM2XicD7yTtJ/do1Zi7r3P34939YOAjM5sBTE0Ks7j4pwkKsnhnAkvNrHvcsdtIHNLYAphEsFB0i2zlLyLSWKjAEhGRdCpMdgG84+5vpwquDndfQ8WZBXerbntmdm3yjITu/o67jwH6A6vjTh1kZoXVfa0Inkrar5V7wMws38xuAf4bHjqC9MMRTyaYGCPeAcC8cKZI3H09cCSJf7eya2+rcdIiIo2MCiwREamUu78GvBB3KEb0qdkzeZ1FBL1j2RADRlXyOiuAY4AN4SEjmMChtk0nWMS5zF5mtldlwdVhZu2AxcBlwJvAGHffnu6acBbFHxFMZBG/YHMfgqKqLO4tgqIweVHpc5JmlxQRafJUYImISFXie7HWEUyDnnXhxBR3Zqm5y8ysdaoT7v4J8Gy4+7a7Jy98nHXhUMjkqemrnGQj7JEanuHL3AB8N9x+oqriysyONrMfeeBO4FDgo7iQjmHcL82ss7tvdfexBBNolN1Ttgu1cz+ZiEiDpQJLRETK5AOtUhz/Gzu/eN8XTk4RL/k+nOaVtN+ZYL2rdC6l4nC6ZMmvl6oHZQ9gRqp7hMwsD+gd7v66itdK7t2q9j1H7j4DmBh36BdmdmRl8eHCwAuIm+0vxTph8fvHxW2faGb7mdnpJN7vlXz9b8qGSIa9lRPizr0aPufH5x2+j7J75Na5e/zCziIiTZ4KLBERwczaA+OB75jZj+PPufsO4I8EvRZTkq4z4AdJzfVKHv4WTr2+P/ArM6u0xyMs3k6l4v0+8Xl+L+nwiZUMUxtCMGHD4LCoKitaHiK4z+had/9LZbmEhcegpMODzCxVEZoRd78K+DHwOUGxNs/MrjCz8nvOzKyjmV1AMDRzmrvHrxeWfO/Wt+O2343b7kMwTHAQO+/HAjjNzB5Iipsf99+rbKr3qeG9cWV+ZmZ3mVnrcIHivcPj16d/xyIiTY8KLBGRJs7Mfg2sB44l+Hdhlpl9ZWb7xIXdT/Bl/7O4664lmP0veVHf9sDbZvaBmR1hZpvZORvhEOBzM/tjZfnEzSyYMHTPzFYBnwA9ki75MfClmf25rAmCRZHbECxcfFFZPsBrBIXNQHe/obIczGwhwd+kf9KpAWH+Cyu7tiru/jeCAuVcYBHwc4JZ/z4xs/8AfwlzPNTdy4shMxtBcI9VvPPN7O/h9sXAEoKp9f8FnOzuZwGXAGvC4/8Brkpq42jgXTP7jGCGyBuAc1KkfgHBf++PCHrFznD3rMz2KCLSmJi713UOIiIiIiIijYJ6sERERERERLJEBZb8//brWAAAAABgkL/1JHaWRQAAwESwAAAAJoIFAAAwESwAAICJYAEAAEwECwAAYCJYAAAAE8ECAACYCBYAAMAkbthyT+KzStYAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 864x252 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot var \n",
    "import tikzplotlib as tpl\n",
    "\n",
    "fig = plt.figure()\n",
    "\n",
    "plt.rcParams[\"figure.figsize\"] = (12, 3.5)\n",
    "plt.rcParams['xtick.labelsize'] = 20\n",
    "plt.rcParams['ytick.labelsize'] = 18\n",
    "plt.rcParams[\"font.family\"] = \"serif\"\n",
    "plt.rcParams[\"font.serif\"] = \"Times New Roman\"\n",
    "\n",
    "plt.plot(classes, var_alphas_in, 'ro', markersize=12, label='In Dist')\n",
    "plt.plot(classes_out, var_alphas_out, 'bo', markersize=12, label='Out Dist')\n",
    "plt.xlabel('MNIST Class', fontdict={'fontsize':25})\n",
    "plt.ylabel('Mean Variance', fontdict={'fontsize':25})\n",
    "plt.legend(loc='upper left', prop={'size': 25});\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig('figures/MNIST3VarianceOOD.pdf')\n",
    "\n",
    "plt.show()\n",
    "\n",
    "#tpl.save('MNIST3VarianceOOD.tex', figure=fig, tex_relative_path_to_data='.figures', figurewidth='\\\\figwidth', figureheight='\\\\figheight')\n",
    "#tpl.save('MNIST3VarianceOOD.tex', figure=fig, figurewidth='\\\\figwidth', figureheight='\\\\figheight',\n",
    "#         extra_axis_parameters={'xtick align=outside', 'ytick align=outside', 'xtick pos=left', 'ytick pos=left', 'legend pos=north west'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
